ActivityManagerService.java revision 37a40c24deb02bca3868a8085069afae112f22e4
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_PRIV;
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.BroadcastOptions;
43import android.app.IActivityContainer;
44import android.app.IActivityContainerCallback;
45import android.app.IAppTask;
46import android.app.ITaskStackListener;
47import android.app.ProfilerInfo;
48import android.app.assist.AssistContent;
49import android.app.assist.AssistStructure;
50import android.app.usage.UsageEvents;
51import android.app.usage.UsageStatsManagerInternal;
52import android.appwidget.AppWidgetManager;
53import android.content.pm.PermissionInfo;
54import android.content.res.Resources;
55import android.graphics.Bitmap;
56import android.graphics.Point;
57import android.graphics.Rect;
58import android.os.BatteryStats;
59import android.os.PersistableBundle;
60import android.os.PowerManager;
61import android.os.Trace;
62import android.os.TransactionTooLargeException;
63import android.os.WorkSource;
64import android.os.storage.IMountService;
65import android.os.storage.StorageManager;
66import android.service.voice.IVoiceInteractionSession;
67import android.util.ArrayMap;
68import android.util.ArraySet;
69import android.util.DebugUtils;
70import android.util.SparseIntArray;
71import android.view.Display;
72
73import com.android.internal.R;
74import com.android.internal.annotations.GuardedBy;
75import com.android.internal.app.DumpHeapActivity;
76import com.android.internal.app.IAppOpsService;
77import com.android.internal.app.IVoiceInteractor;
78import com.android.internal.app.ProcessMap;
79import com.android.internal.app.ProcessStats;
80import com.android.internal.os.BackgroundThread;
81import com.android.internal.os.BatteryStatsImpl;
82import com.android.internal.os.IResultReceiver;
83import com.android.internal.os.ProcessCpuTracker;
84import com.android.internal.os.TransferPipe;
85import com.android.internal.os.Zygote;
86import com.android.internal.util.ArrayUtils;
87import com.android.internal.util.FastPrintWriter;
88import com.android.internal.util.FastXmlSerializer;
89import com.android.internal.util.MemInfoReader;
90import com.android.internal.util.Preconditions;
91import com.android.server.AppOpsService;
92import com.android.server.AttributeCache;
93import com.android.server.DeviceIdleController;
94import com.android.server.IntentResolver;
95import com.android.server.LocalServices;
96import com.android.server.ServiceThread;
97import com.android.server.SystemService;
98import com.android.server.SystemServiceManager;
99import com.android.server.Watchdog;
100import com.android.server.am.ActivityStack.ActivityState;
101import com.android.server.firewall.IntentFirewall;
102import com.android.server.pm.Installer;
103import com.android.server.pm.UserManagerService;
104import com.android.server.statusbar.StatusBarManagerInternal;
105import com.android.server.wm.AppTransition;
106import com.android.server.wm.WindowManagerService;
107import com.google.android.collect.Lists;
108import com.google.android.collect.Maps;
109
110import libcore.io.IoUtils;
111import libcore.util.EmptyArray;
112
113import org.xmlpull.v1.XmlPullParser;
114import org.xmlpull.v1.XmlPullParserException;
115import org.xmlpull.v1.XmlSerializer;
116
117import android.app.Activity;
118import android.app.ActivityManager;
119import android.app.ActivityManager.RunningTaskInfo;
120import android.app.ActivityManager.StackInfo;
121import android.app.ActivityManagerInternal;
122import android.app.ActivityManagerInternal.SleepToken;
123import android.app.ActivityManagerNative;
124import android.app.ActivityOptions;
125import android.app.ActivityThread;
126import android.app.AlertDialog;
127import android.app.AppGlobals;
128import android.app.ApplicationErrorReport;
129import android.app.Dialog;
130import android.app.IActivityController;
131import android.app.IApplicationThread;
132import android.app.IInstrumentationWatcher;
133import android.app.INotificationManager;
134import android.app.IProcessObserver;
135import android.app.IServiceConnection;
136import android.app.IStopUserCallback;
137import android.app.IUidObserver;
138import android.app.IUiAutomationConnection;
139import android.app.IUserSwitchObserver;
140import android.app.Instrumentation;
141import android.app.Notification;
142import android.app.NotificationManager;
143import android.app.PendingIntent;
144import android.app.backup.IBackupManager;
145import android.content.ActivityNotFoundException;
146import android.content.BroadcastReceiver;
147import android.content.ClipData;
148import android.content.ComponentCallbacks2;
149import android.content.ComponentName;
150import android.content.ContentProvider;
151import android.content.ContentResolver;
152import android.content.Context;
153import android.content.DialogInterface;
154import android.content.IContentProvider;
155import android.content.IIntentReceiver;
156import android.content.IIntentSender;
157import android.content.Intent;
158import android.content.IntentFilter;
159import android.content.IntentSender;
160import android.content.pm.ActivityInfo;
161import android.content.pm.ApplicationInfo;
162import android.content.pm.ConfigurationInfo;
163import android.content.pm.IPackageDataObserver;
164import android.content.pm.IPackageManager;
165import android.content.pm.InstrumentationInfo;
166import android.content.pm.PackageInfo;
167import android.content.pm.PackageManager;
168import android.content.pm.ParceledListSlice;
169import android.content.pm.UserInfo;
170import android.content.pm.PackageManager.NameNotFoundException;
171import android.content.pm.PathPermission;
172import android.content.pm.ProviderInfo;
173import android.content.pm.ResolveInfo;
174import android.content.pm.ServiceInfo;
175import android.content.res.CompatibilityInfo;
176import android.content.res.Configuration;
177import android.net.Proxy;
178import android.net.ProxyInfo;
179import android.net.Uri;
180import android.os.Binder;
181import android.os.Build;
182import android.os.Bundle;
183import android.os.Debug;
184import android.os.DropBoxManager;
185import android.os.Environment;
186import android.os.FactoryTest;
187import android.os.FileObserver;
188import android.os.FileUtils;
189import android.os.Handler;
190import android.os.IBinder;
191import android.os.IPermissionController;
192import android.os.IProcessInfoService;
193import android.os.IRemoteCallback;
194import android.os.IUserManager;
195import android.os.Looper;
196import android.os.Message;
197import android.os.Parcel;
198import android.os.ParcelFileDescriptor;
199import android.os.PowerManagerInternal;
200import android.os.Process;
201import android.os.RemoteCallbackList;
202import android.os.RemoteException;
203import android.os.SELinux;
204import android.os.ServiceManager;
205import android.os.StrictMode;
206import android.os.SystemClock;
207import android.os.SystemProperties;
208import android.os.UpdateLock;
209import android.os.UserHandle;
210import android.os.UserManager;
211import android.provider.Settings;
212import android.text.format.DateUtils;
213import android.text.format.Time;
214import android.util.AtomicFile;
215import android.util.EventLog;
216import android.util.Log;
217import android.util.Pair;
218import android.util.PrintWriterPrinter;
219import android.util.Slog;
220import android.util.SparseArray;
221import android.util.TimeUtils;
222import android.util.Xml;
223import android.view.Gravity;
224import android.view.LayoutInflater;
225import android.view.View;
226import android.view.WindowManager;
227
228import dalvik.system.VMRuntime;
229
230import java.io.BufferedInputStream;
231import java.io.BufferedOutputStream;
232import java.io.DataInputStream;
233import java.io.DataOutputStream;
234import java.io.File;
235import java.io.FileDescriptor;
236import java.io.FileInputStream;
237import java.io.FileNotFoundException;
238import java.io.FileOutputStream;
239import java.io.IOException;
240import java.io.InputStreamReader;
241import java.io.PrintWriter;
242import java.io.StringWriter;
243import java.lang.ref.WeakReference;
244import java.nio.charset.StandardCharsets;
245import java.util.ArrayList;
246import java.util.Arrays;
247import java.util.Collections;
248import java.util.Comparator;
249import java.util.HashMap;
250import java.util.HashSet;
251import java.util.Iterator;
252import java.util.List;
253import java.util.Locale;
254import java.util.Map;
255import java.util.Set;
256import java.util.concurrent.atomic.AtomicBoolean;
257import java.util.concurrent.atomic.AtomicLong;
258
259public final class ActivityManagerService extends ActivityManagerNative
260        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
261
262    // File that stores last updated system version and called preboot receivers
263    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
264
265    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
266    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
267    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
268    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
269    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
270    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
271    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
272    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
273    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
274    private static final String TAG_LRU = TAG + POSTFIX_LRU;
275    private static final String TAG_MU = TAG + POSTFIX_MU;
276    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
277    private static final String TAG_POWER = TAG + POSTFIX_POWER;
278    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
279    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
280    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
281    private static final String TAG_PSS = TAG + POSTFIX_PSS;
282    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
283    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
284    private static final String TAG_STACK = TAG + POSTFIX_STACK;
285    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
286    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
287    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
288    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
289    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
290
291    /** Control over CPU and battery monitoring */
292    // write battery stats every 30 minutes.
293    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
294    static final boolean MONITOR_CPU_USAGE = true;
295    // don't sample cpu less than every 5 seconds.
296    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
297    // wait possibly forever for next cpu sample.
298    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
299    static final boolean MONITOR_THREAD_CPU_USAGE = false;
300
301    // The flags that are set for all calls we make to the package manager.
302    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
303
304    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
305
306    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
307
308    // Amount of time after a call to stopAppSwitches() during which we will
309    // prevent further untrusted switches from happening.
310    static final long APP_SWITCH_DELAY_TIME = 5*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.
314    static final int PROC_START_TIMEOUT = 10*1000;
315
316    // How long we wait for a launched process to attach to the activity manager
317    // before we decide it's never going to come up for real, when the process was
318    // started with a wrapper for instrumentation (such as Valgrind) because it
319    // could take much longer than usual.
320    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
321
322    // How long to wait after going idle before forcing apps to GC.
323    static final int GC_TIMEOUT = 5*1000;
324
325    // The minimum amount of time between successive GC requests for a process.
326    static final int GC_MIN_INTERVAL = 60*1000;
327
328    // The minimum amount of time between successive PSS requests for a process.
329    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
330
331    // The minimum amount of time between successive PSS requests for a process
332    // when the request is due to the memory state being lowered.
333    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
334
335    // The rate at which we check for apps using excessive power -- 15 mins.
336    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
337
338    // The minimum sample duration we will allow before deciding we have
339    // enough data on wake locks to start killing things.
340    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
341
342    // The minimum sample duration we will allow before deciding we have
343    // enough data on CPU usage to start killing things.
344    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
345
346    // How long we allow a receiver to run before giving up on it.
347    static final int BROADCAST_FG_TIMEOUT = 10*1000;
348    static final int BROADCAST_BG_TIMEOUT = 60*1000;
349
350    // How long we wait until we timeout on key dispatching.
351    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
352
353    // How long we wait until we timeout on key dispatching during instrumentation.
354    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
355
356    // Amount of time we wait for observers to handle a user switch before
357    // giving up on them and unfreezing the screen.
358    static final int USER_SWITCH_TIMEOUT = 2*1000;
359
360    // This is the amount of time an app needs to be running a foreground service before
361    // we will consider it to be doing interaction for usage stats.
362    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
363
364    // Maximum number of users we allow to be running at a time.
365    static final int MAX_RUNNING_USERS = 3;
366
367    // How long to wait in getAssistContextExtras for the activity and foreground services
368    // to respond with the result.
369    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
370
371    // How long top wait when going through the modern assist (which doesn't need to block
372    // on getting this result before starting to launch its UI).
373    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
374
375    // Maximum number of persisted Uri grants a package is allowed
376    static final int MAX_PERSISTED_URI_GRANTS = 128;
377
378    static final int MY_PID = Process.myPid();
379
380    static final String[] EMPTY_STRING_ARRAY = new String[0];
381
382    // How many bytes to write into the dropbox log before truncating
383    static final int DROPBOX_MAX_SIZE = 256 * 1024;
384
385    // Access modes for handleIncomingUser.
386    static final int ALLOW_NON_FULL = 0;
387    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
388    static final int ALLOW_FULL_ONLY = 2;
389
390    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
391
392    // Delay in notifying task stack change listeners (in millis)
393    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
394
395    // Necessary ApplicationInfo flags to mark an app as persistent
396    private static final int PERSISTENT_MASK =
397            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
398
399    /** All system services */
400    SystemServiceManager mSystemServiceManager;
401
402    private Installer mInstaller;
403
404    /** Run all ActivityStacks through this */
405    ActivityStackSupervisor mStackSupervisor;
406
407    /** Task stack change listeners. */
408    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
409            new RemoteCallbackList<ITaskStackListener>();
410
411    public IntentFirewall mIntentFirewall;
412
413    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
414    // default actuion automatically.  Important for devices without direct input
415    // devices.
416    private boolean mShowDialogs = true;
417
418    BroadcastQueue mFgBroadcastQueue;
419    BroadcastQueue mBgBroadcastQueue;
420    // Convenient for easy iteration over the queues. Foreground is first
421    // so that dispatch of foreground broadcasts gets precedence.
422    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
423
424    BroadcastQueue broadcastQueueForIntent(Intent intent) {
425        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
426        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
427                "Broadcast intent " + intent + " on "
428                + (isFg ? "foreground" : "background") + " queue");
429        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
430    }
431
432    /**
433     * Activity we have told the window manager to have key focus.
434     */
435    ActivityRecord mFocusedActivity = null;
436
437    /**
438     * User id of the last activity mFocusedActivity was set to.
439     */
440    private int mLastFocusedUserId;
441
442    /**
443     * If non-null, we are tracking the time the user spends in the currently focused app.
444     */
445    private AppTimeTracker mCurAppTimeTracker;
446
447    /**
448     * List of intents that were used to start the most recent tasks.
449     */
450    private final RecentTasks mRecentTasks;
451
452    /**
453     * For addAppTask: cached of the last activity component that was added.
454     */
455    ComponentName mLastAddedTaskComponent;
456
457    /**
458     * For addAppTask: cached of the last activity uid that was added.
459     */
460    int mLastAddedTaskUid;
461
462    /**
463     * For addAppTask: cached of the last ActivityInfo that was added.
464     */
465    ActivityInfo mLastAddedTaskActivity;
466
467    /**
468     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
469     */
470    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
471
472    /**
473     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
474     */
475    String mDeviceOwnerName;
476
477    public class PendingAssistExtras extends Binder implements Runnable {
478        public final ActivityRecord activity;
479        public final Bundle extras;
480        public final Intent intent;
481        public final String hint;
482        public final IResultReceiver receiver;
483        public final int userHandle;
484        public boolean haveResult = false;
485        public Bundle result = null;
486        public AssistStructure structure = null;
487        public AssistContent content = null;
488        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
489                String _hint, IResultReceiver _receiver, int _userHandle) {
490            activity = _activity;
491            extras = _extras;
492            intent = _intent;
493            hint = _hint;
494            receiver = _receiver;
495            userHandle = _userHandle;
496        }
497        @Override
498        public void run() {
499            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
500            synchronized (ActivityManagerService.this) {
501                synchronized (this) {
502                    haveResult = true;
503                    notifyAll();
504                }
505                pendingAssistExtrasTimedOutLocked(this);
506            }
507        }
508    }
509
510    final ArrayList<PendingAssistExtras> mPendingAssistExtras
511            = new ArrayList<PendingAssistExtras>();
512
513    /**
514     * Process management.
515     */
516    final ProcessList mProcessList = new ProcessList();
517
518    /**
519     * All of the applications we currently have running organized by name.
520     * The keys are strings of the application package name (as
521     * returned by the package manager), and the keys are ApplicationRecord
522     * objects.
523     */
524    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
525
526    /**
527     * Tracking long-term execution of processes to look for abuse and other
528     * bad app behavior.
529     */
530    final ProcessStatsService mProcessStats;
531
532    /**
533     * The currently running isolated processes.
534     */
535    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
536
537    /**
538     * Counter for assigning isolated process uids, to avoid frequently reusing the
539     * same ones.
540     */
541    int mNextIsolatedProcessUid = 0;
542
543    /**
544     * The currently running heavy-weight process, if any.
545     */
546    ProcessRecord mHeavyWeightProcess = null;
547
548    /**
549     * The last time that various processes have crashed.
550     */
551    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
552
553    /**
554     * Information about a process that is currently marked as bad.
555     */
556    static final class BadProcessInfo {
557        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
558            this.time = time;
559            this.shortMsg = shortMsg;
560            this.longMsg = longMsg;
561            this.stack = stack;
562        }
563
564        final long time;
565        final String shortMsg;
566        final String longMsg;
567        final String stack;
568    }
569
570    /**
571     * Set of applications that we consider to be bad, and will reject
572     * incoming broadcasts from (which the user has no control over).
573     * Processes are added to this set when they have crashed twice within
574     * a minimum amount of time; they are removed from it when they are
575     * later restarted (hopefully due to some user action).  The value is the
576     * time it was added to the list.
577     */
578    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
579
580    /**
581     * All of the processes we currently have running organized by pid.
582     * The keys are the pid running the application.
583     *
584     * <p>NOTE: This object is protected by its own lock, NOT the global
585     * activity manager lock!
586     */
587    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
588
589    /**
590     * All of the processes that have been forced to be foreground.  The key
591     * is the pid of the caller who requested it (we hold a death
592     * link on it).
593     */
594    abstract class ForegroundToken implements IBinder.DeathRecipient {
595        int pid;
596        IBinder token;
597    }
598    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
599
600    /**
601     * List of records for processes that someone had tried to start before the
602     * system was ready.  We don't start them at that point, but ensure they
603     * are started by the time booting is complete.
604     */
605    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
606
607    /**
608     * List of persistent applications that are in the process
609     * of being started.
610     */
611    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
612
613    /**
614     * Processes that are being forcibly torn down.
615     */
616    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
617
618    /**
619     * List of running applications, sorted by recent usage.
620     * The first entry in the list is the least recently used.
621     */
622    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
623
624    /**
625     * Where in mLruProcesses that the processes hosting activities start.
626     */
627    int mLruProcessActivityStart = 0;
628
629    /**
630     * Where in mLruProcesses that the processes hosting services start.
631     * This is after (lower index) than mLruProcessesActivityStart.
632     */
633    int mLruProcessServiceStart = 0;
634
635    /**
636     * List of processes that should gc as soon as things are idle.
637     */
638    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
639
640    /**
641     * Processes we want to collect PSS data from.
642     */
643    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
644
645    /**
646     * Last time we requested PSS data of all processes.
647     */
648    long mLastFullPssTime = SystemClock.uptimeMillis();
649
650    /**
651     * If set, the next time we collect PSS data we should do a full collection
652     * with data from native processes and the kernel.
653     */
654    boolean mFullPssPending = false;
655
656    /**
657     * This is the process holding what we currently consider to be
658     * the "home" activity.
659     */
660    ProcessRecord mHomeProcess;
661
662    /**
663     * This is the process holding the activity the user last visited that
664     * is in a different process from the one they are currently in.
665     */
666    ProcessRecord mPreviousProcess;
667
668    /**
669     * The time at which the previous process was last visible.
670     */
671    long mPreviousProcessVisibleTime;
672
673    /**
674     * Track all uids that have actively running processes.
675     */
676    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
677
678    /**
679     * Which users have been started, so are allowed to run code.
680     */
681    final SparseArray<UserState> mStartedUsers = new SparseArray<>();
682
683    /**
684     * LRU list of history of current users.  Most recently current is at the end.
685     */
686    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
687
688    /**
689     * Constant array of the users that are currently started.
690     */
691    int[] mStartedUserArray = new int[] { 0 };
692
693    /**
694     * Registered observers of the user switching mechanics.
695     */
696    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
697            = new RemoteCallbackList<IUserSwitchObserver>();
698
699    /**
700     * Currently active user switch.
701     */
702    Object mCurUserSwitchCallback;
703
704    /**
705     * Packages that the user has asked to have run in screen size
706     * compatibility mode instead of filling the screen.
707     */
708    final CompatModePackages mCompatModePackages;
709
710    /**
711     * Set of IntentSenderRecord objects that are currently active.
712     */
713    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
714            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
715
716    /**
717     * Fingerprints (hashCode()) of stack traces that we've
718     * already logged DropBox entries for.  Guarded by itself.  If
719     * something (rogue user app) forces this over
720     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
721     */
722    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
723    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
724
725    /**
726     * Strict Mode background batched logging state.
727     *
728     * The string buffer is guarded by itself, and its lock is also
729     * used to determine if another batched write is already
730     * in-flight.
731     */
732    private final StringBuilder mStrictModeBuffer = new StringBuilder();
733
734    /**
735     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
736     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
737     */
738    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
739
740    /**
741     * Resolver for broadcast intents to registered receivers.
742     * Holds BroadcastFilter (subclass of IntentFilter).
743     */
744    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
745            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
746        @Override
747        protected boolean allowFilterResult(
748                BroadcastFilter filter, List<BroadcastFilter> dest) {
749            IBinder target = filter.receiverList.receiver.asBinder();
750            for (int i = dest.size() - 1; i >= 0; i--) {
751                if (dest.get(i).receiverList.receiver.asBinder() == target) {
752                    return false;
753                }
754            }
755            return true;
756        }
757
758        @Override
759        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
760            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
761                    || userId == filter.owningUserId) {
762                return super.newResult(filter, match, userId);
763            }
764            return null;
765        }
766
767        @Override
768        protected BroadcastFilter[] newArray(int size) {
769            return new BroadcastFilter[size];
770        }
771
772        @Override
773        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
774            return packageName.equals(filter.packageName);
775        }
776    };
777
778    /**
779     * State of all active sticky broadcasts per user.  Keys are the action of the
780     * sticky Intent, values are an ArrayList of all broadcasted intents with
781     * that action (which should usually be one).  The SparseArray is keyed
782     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
783     * for stickies that are sent to all users.
784     */
785    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
786            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
787
788    final ActiveServices mServices;
789
790    final static class Association {
791        final int mSourceUid;
792        final String mSourceProcess;
793        final int mTargetUid;
794        final ComponentName mTargetComponent;
795        final String mTargetProcess;
796
797        int mCount;
798        long mTime;
799
800        int mNesting;
801        long mStartTime;
802
803        Association(int sourceUid, String sourceProcess, int targetUid,
804                ComponentName targetComponent, String targetProcess) {
805            mSourceUid = sourceUid;
806            mSourceProcess = sourceProcess;
807            mTargetUid = targetUid;
808            mTargetComponent = targetComponent;
809            mTargetProcess = targetProcess;
810        }
811    }
812
813    /**
814     * When service association tracking is enabled, this is all of the associations we
815     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
816     * -> association data.
817     */
818    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
819            mAssociations = new SparseArray<>();
820    boolean mTrackingAssociations;
821
822    /**
823     * Backup/restore process management
824     */
825    String mBackupAppName = null;
826    BackupRecord mBackupTarget = null;
827
828    final ProviderMap mProviderMap;
829
830    /**
831     * List of content providers who have clients waiting for them.  The
832     * application is currently being launched and the provider will be
833     * removed from this list once it is published.
834     */
835    final ArrayList<ContentProviderRecord> mLaunchingProviders
836            = new ArrayList<ContentProviderRecord>();
837
838    /**
839     * File storing persisted {@link #mGrantedUriPermissions}.
840     */
841    private final AtomicFile mGrantFile;
842
843    /** XML constants used in {@link #mGrantFile} */
844    private static final String TAG_URI_GRANTS = "uri-grants";
845    private static final String TAG_URI_GRANT = "uri-grant";
846    private static final String ATTR_USER_HANDLE = "userHandle";
847    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
848    private static final String ATTR_TARGET_USER_ID = "targetUserId";
849    private static final String ATTR_SOURCE_PKG = "sourcePkg";
850    private static final String ATTR_TARGET_PKG = "targetPkg";
851    private static final String ATTR_URI = "uri";
852    private static final String ATTR_MODE_FLAGS = "modeFlags";
853    private static final String ATTR_CREATED_TIME = "createdTime";
854    private static final String ATTR_PREFIX = "prefix";
855
856    /**
857     * Global set of specific {@link Uri} permissions that have been granted.
858     * This optimized lookup structure maps from {@link UriPermission#targetUid}
859     * to {@link UriPermission#uri} to {@link UriPermission}.
860     */
861    @GuardedBy("this")
862    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
863            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
864
865    public static class GrantUri {
866        public final int sourceUserId;
867        public final Uri uri;
868        public boolean prefix;
869
870        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
871            this.sourceUserId = sourceUserId;
872            this.uri = uri;
873            this.prefix = prefix;
874        }
875
876        @Override
877        public int hashCode() {
878            int hashCode = 1;
879            hashCode = 31 * hashCode + sourceUserId;
880            hashCode = 31 * hashCode + uri.hashCode();
881            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
882            return hashCode;
883        }
884
885        @Override
886        public boolean equals(Object o) {
887            if (o instanceof GrantUri) {
888                GrantUri other = (GrantUri) o;
889                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
890                        && prefix == other.prefix;
891            }
892            return false;
893        }
894
895        @Override
896        public String toString() {
897            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
898            if (prefix) result += " [prefix]";
899            return result;
900        }
901
902        public String toSafeString() {
903            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
904            if (prefix) result += " [prefix]";
905            return result;
906        }
907
908        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
909            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
910                    ContentProvider.getUriWithoutUserId(uri), false);
911        }
912    }
913
914    CoreSettingsObserver mCoreSettingsObserver;
915
916    /**
917     * Thread-local storage used to carry caller permissions over through
918     * indirect content-provider access.
919     */
920    private class Identity {
921        public final IBinder token;
922        public final int pid;
923        public final int uid;
924
925        Identity(IBinder _token, int _pid, int _uid) {
926            token = _token;
927            pid = _pid;
928            uid = _uid;
929        }
930    }
931
932    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
933
934    /**
935     * All information we have collected about the runtime performance of
936     * any user id that can impact battery performance.
937     */
938    final BatteryStatsService mBatteryStatsService;
939
940    /**
941     * Information about component usage
942     */
943    UsageStatsManagerInternal mUsageStatsService;
944
945    /**
946     * Access to DeviceIdleController service.
947     */
948    DeviceIdleController.LocalService mLocalDeviceIdleController;
949
950    /**
951     * Information about and control over application operations
952     */
953    final AppOpsService mAppOpsService;
954
955    /**
956     * Save recent tasks information across reboots.
957     */
958    final TaskPersister mTaskPersister;
959
960    /**
961     * Current configuration information.  HistoryRecord objects are given
962     * a reference to this object to indicate which configuration they are
963     * currently running in, so this object must be kept immutable.
964     */
965    Configuration mConfiguration = new Configuration();
966
967    /**
968     * Current sequencing integer of the configuration, for skipping old
969     * configurations.
970     */
971    int mConfigurationSeq = 0;
972
973    /**
974     * Hardware-reported OpenGLES version.
975     */
976    final int GL_ES_VERSION;
977
978    /**
979     * List of initialization arguments to pass to all processes when binding applications to them.
980     * For example, references to the commonly used services.
981     */
982    HashMap<String, IBinder> mAppBindArgs;
983
984    /**
985     * Temporary to avoid allocations.  Protected by main lock.
986     */
987    final StringBuilder mStringBuilder = new StringBuilder(256);
988
989    /**
990     * Used to control how we initialize the service.
991     */
992    ComponentName mTopComponent;
993    String mTopAction = Intent.ACTION_MAIN;
994    String mTopData;
995    boolean mProcessesReady = false;
996    boolean mSystemReady = false;
997    boolean mBooting = false;
998    boolean mCallFinishBooting = false;
999    boolean mBootAnimationComplete = false;
1000    boolean mWaitingUpdate = false;
1001    boolean mDidUpdate = false;
1002    boolean mOnBattery = false;
1003    boolean mLaunchWarningShown = false;
1004
1005    Context mContext;
1006
1007    int mFactoryTest;
1008
1009    boolean mCheckedForSetup;
1010
1011    /**
1012     * The time at which we will allow normal application switches again,
1013     * after a call to {@link #stopAppSwitches()}.
1014     */
1015    long mAppSwitchesAllowedTime;
1016
1017    /**
1018     * This is set to true after the first switch after mAppSwitchesAllowedTime
1019     * is set; any switches after that will clear the time.
1020     */
1021    boolean mDidAppSwitch;
1022
1023    /**
1024     * Last time (in realtime) at which we checked for power usage.
1025     */
1026    long mLastPowerCheckRealtime;
1027
1028    /**
1029     * Last time (in uptime) at which we checked for power usage.
1030     */
1031    long mLastPowerCheckUptime;
1032
1033    /**
1034     * Set while we are wanting to sleep, to prevent any
1035     * activities from being started/resumed.
1036     */
1037    private boolean mSleeping = false;
1038
1039    /**
1040     * The process state used for processes that are running the top activities.
1041     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1042     */
1043    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1044
1045    /**
1046     * Set while we are running a voice interaction.  This overrides
1047     * sleeping while it is active.
1048     */
1049    private IVoiceInteractionSession mRunningVoice;
1050
1051    /**
1052     * For some direct access we need to power manager.
1053     */
1054    PowerManagerInternal mLocalPowerManager;
1055
1056    /**
1057     * We want to hold a wake lock while running a voice interaction session, since
1058     * this may happen with the screen off and we need to keep the CPU running to
1059     * be able to continue to interact with the user.
1060     */
1061    PowerManager.WakeLock mVoiceWakeLock;
1062
1063    /**
1064     * State of external calls telling us if the device is awake or asleep.
1065     */
1066    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1067
1068    /**
1069     * A list of tokens that cause the top activity to be put to sleep.
1070     * They are used by components that may hide and block interaction with underlying
1071     * activities.
1072     */
1073    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1074
1075    static final int LOCK_SCREEN_HIDDEN = 0;
1076    static final int LOCK_SCREEN_LEAVING = 1;
1077    static final int LOCK_SCREEN_SHOWN = 2;
1078    /**
1079     * State of external call telling us if the lock screen is shown.
1080     */
1081    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1082
1083    /**
1084     * Set if we are shutting down the system, similar to sleeping.
1085     */
1086    boolean mShuttingDown = false;
1087
1088    /**
1089     * Current sequence id for oom_adj computation traversal.
1090     */
1091    int mAdjSeq = 0;
1092
1093    /**
1094     * Current sequence id for process LRU updating.
1095     */
1096    int mLruSeq = 0;
1097
1098    /**
1099     * Keep track of the non-cached/empty process we last found, to help
1100     * determine how to distribute cached/empty processes next time.
1101     */
1102    int mNumNonCachedProcs = 0;
1103
1104    /**
1105     * Keep track of the number of cached hidden procs, to balance oom adj
1106     * distribution between those and empty procs.
1107     */
1108    int mNumCachedHiddenProcs = 0;
1109
1110    /**
1111     * Keep track of the number of service processes we last found, to
1112     * determine on the next iteration which should be B services.
1113     */
1114    int mNumServiceProcs = 0;
1115    int mNewNumAServiceProcs = 0;
1116    int mNewNumServiceProcs = 0;
1117
1118    /**
1119     * Allow the current computed overall memory level of the system to go down?
1120     * This is set to false when we are killing processes for reasons other than
1121     * memory management, so that the now smaller process list will not be taken as
1122     * an indication that memory is tighter.
1123     */
1124    boolean mAllowLowerMemLevel = false;
1125
1126    /**
1127     * The last computed memory level, for holding when we are in a state that
1128     * processes are going away for other reasons.
1129     */
1130    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1131
1132    /**
1133     * The last total number of process we have, to determine if changes actually look
1134     * like a shrinking number of process due to lower RAM.
1135     */
1136    int mLastNumProcesses;
1137
1138    /**
1139     * The uptime of the last time we performed idle maintenance.
1140     */
1141    long mLastIdleTime = SystemClock.uptimeMillis();
1142
1143    /**
1144     * Total time spent with RAM that has been added in the past since the last idle time.
1145     */
1146    long mLowRamTimeSinceLastIdle = 0;
1147
1148    /**
1149     * If RAM is currently low, when that horrible situation started.
1150     */
1151    long mLowRamStartTime = 0;
1152
1153    /**
1154     * For reporting to battery stats the current top application.
1155     */
1156    private String mCurResumedPackage = null;
1157    private int mCurResumedUid = -1;
1158
1159    /**
1160     * For reporting to battery stats the apps currently running foreground
1161     * service.  The ProcessMap is package/uid tuples; each of these contain
1162     * an array of the currently foreground processes.
1163     */
1164    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1165            = new ProcessMap<ArrayList<ProcessRecord>>();
1166
1167    /**
1168     * This is set if we had to do a delayed dexopt of an app before launching
1169     * it, to increase the ANR timeouts in that case.
1170     */
1171    boolean mDidDexOpt;
1172
1173    /**
1174     * Set if the systemServer made a call to enterSafeMode.
1175     */
1176    boolean mSafeMode;
1177
1178    /**
1179     * If true, we are running under a test environment so will sample PSS from processes
1180     * much more rapidly to try to collect better data when the tests are rapidly
1181     * running through apps.
1182     */
1183    boolean mTestPssMode = false;
1184
1185    String mDebugApp = null;
1186    boolean mWaitForDebugger = false;
1187    boolean mDebugTransient = false;
1188    String mOrigDebugApp = null;
1189    boolean mOrigWaitForDebugger = false;
1190    boolean mAlwaysFinishActivities = false;
1191    IActivityController mController = null;
1192    String mProfileApp = null;
1193    ProcessRecord mProfileProc = null;
1194    String mProfileFile;
1195    ParcelFileDescriptor mProfileFd;
1196    int mSamplingInterval = 0;
1197    boolean mAutoStopProfiler = false;
1198    int mProfileType = 0;
1199    String mOpenGlTraceApp = null;
1200    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1201    String mMemWatchDumpProcName;
1202    String mMemWatchDumpFile;
1203    int mMemWatchDumpPid;
1204    int mMemWatchDumpUid;
1205
1206    final long[] mTmpLong = new long[1];
1207
1208    static final class ProcessChangeItem {
1209        static final int CHANGE_ACTIVITIES = 1<<0;
1210        static final int CHANGE_PROCESS_STATE = 1<<1;
1211        int changes;
1212        int uid;
1213        int pid;
1214        int processState;
1215        boolean foregroundActivities;
1216    }
1217
1218    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1219    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1220
1221    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1222    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1223
1224    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1225    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1226
1227    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1228    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1229
1230    /**
1231     * Runtime CPU use collection thread.  This object's lock is used to
1232     * perform synchronization with the thread (notifying it to run).
1233     */
1234    final Thread mProcessCpuThread;
1235
1236    /**
1237     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1238     * Must acquire this object's lock when accessing it.
1239     * NOTE: this lock will be held while doing long operations (trawling
1240     * through all processes in /proc), so it should never be acquired by
1241     * any critical paths such as when holding the main activity manager lock.
1242     */
1243    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1244            MONITOR_THREAD_CPU_USAGE);
1245    final AtomicLong mLastCpuTime = new AtomicLong(0);
1246    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1247
1248    long mLastWriteTime = 0;
1249
1250    /**
1251     * Used to retain an update lock when the foreground activity is in
1252     * immersive mode.
1253     */
1254    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1255
1256    /**
1257     * Set to true after the system has finished booting.
1258     */
1259    boolean mBooted = false;
1260
1261    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1262    int mProcessLimitOverride = -1;
1263
1264    WindowManagerService mWindowManager;
1265
1266    final ActivityThread mSystemThread;
1267
1268    // Holds the current foreground user's id
1269    int mCurrentUserId = 0;
1270    // Holds the target user's id during a user switch
1271    int mTargetUserId = UserHandle.USER_NULL;
1272    // If there are multiple profiles for the current user, their ids are here
1273    // Currently only the primary user can have managed profiles
1274    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1275
1276    /**
1277     * Mapping from each known user ID to the profile group ID it is associated with.
1278     */
1279    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1280
1281    private UserManagerService mUserManager;
1282
1283    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1284        final ProcessRecord mApp;
1285        final int mPid;
1286        final IApplicationThread mAppThread;
1287
1288        AppDeathRecipient(ProcessRecord app, int pid,
1289                IApplicationThread thread) {
1290            if (DEBUG_ALL) Slog.v(
1291                TAG, "New death recipient " + this
1292                + " for thread " + thread.asBinder());
1293            mApp = app;
1294            mPid = pid;
1295            mAppThread = thread;
1296        }
1297
1298        @Override
1299        public void binderDied() {
1300            if (DEBUG_ALL) Slog.v(
1301                TAG, "Death received in " + this
1302                + " for thread " + mAppThread.asBinder());
1303            synchronized(ActivityManagerService.this) {
1304                appDiedLocked(mApp, mPid, mAppThread, true);
1305            }
1306        }
1307    }
1308
1309    static final int SHOW_ERROR_MSG = 1;
1310    static final int SHOW_NOT_RESPONDING_MSG = 2;
1311    static final int SHOW_FACTORY_ERROR_MSG = 3;
1312    static final int UPDATE_CONFIGURATION_MSG = 4;
1313    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1314    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1315    static final int SERVICE_TIMEOUT_MSG = 12;
1316    static final int UPDATE_TIME_ZONE = 13;
1317    static final int SHOW_UID_ERROR_MSG = 14;
1318    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1319    static final int PROC_START_TIMEOUT_MSG = 20;
1320    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1321    static final int KILL_APPLICATION_MSG = 22;
1322    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1323    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1324    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1325    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1326    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1327    static final int CLEAR_DNS_CACHE_MSG = 28;
1328    static final int UPDATE_HTTP_PROXY_MSG = 29;
1329    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1330    static final int DISPATCH_PROCESSES_CHANGED = 31;
1331    static final int DISPATCH_PROCESS_DIED = 32;
1332    static final int REPORT_MEM_USAGE_MSG = 33;
1333    static final int REPORT_USER_SWITCH_MSG = 34;
1334    static final int CONTINUE_USER_SWITCH_MSG = 35;
1335    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1336    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1337    static final int PERSIST_URI_GRANTS_MSG = 38;
1338    static final int REQUEST_ALL_PSS_MSG = 39;
1339    static final int START_PROFILES_MSG = 40;
1340    static final int UPDATE_TIME = 41;
1341    static final int SYSTEM_USER_START_MSG = 42;
1342    static final int SYSTEM_USER_CURRENT_MSG = 43;
1343    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1344    static final int FINISH_BOOTING_MSG = 45;
1345    static final int START_USER_SWITCH_MSG = 46;
1346    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1347    static final int DISMISS_DIALOG_MSG = 48;
1348    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1349    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1350    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1351    static final int DELETE_DUMPHEAP_MSG = 52;
1352    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1353    static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1354    static final int REPORT_TIME_TRACKER_MSG = 55;
1355
1356    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1357    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1358    static final int FIRST_COMPAT_MODE_MSG = 300;
1359    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1360
1361    CompatModeDialog mCompatModeDialog;
1362    long mLastMemUsageReportTime = 0;
1363
1364    /**
1365     * Flag whether the current user is a "monkey", i.e. whether
1366     * the UI is driven by a UI automation tool.
1367     */
1368    private boolean mUserIsMonkey;
1369
1370    /** Flag whether the device has a Recents UI */
1371    boolean mHasRecents;
1372
1373    /** The dimensions of the thumbnails in the Recents UI. */
1374    int mThumbnailWidth;
1375    int mThumbnailHeight;
1376
1377    final ServiceThread mHandlerThread;
1378    final MainHandler mHandler;
1379    final UiHandler mUiHandler;
1380
1381    final class UiHandler extends Handler {
1382        public UiHandler() {
1383            super(com.android.server.UiThread.get().getLooper(), null, true);
1384        }
1385
1386        @Override
1387        public void handleMessage(Message msg) {
1388            switch (msg.what) {
1389            case SHOW_ERROR_MSG: {
1390                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1391                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1392                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1393                synchronized (ActivityManagerService.this) {
1394                    ProcessRecord proc = (ProcessRecord)data.get("app");
1395                    AppErrorResult res = (AppErrorResult) data.get("result");
1396                    if (proc != null && proc.crashDialog != null) {
1397                        Slog.e(TAG, "App already has crash dialog: " + proc);
1398                        if (res != null) {
1399                            res.set(0);
1400                        }
1401                        return;
1402                    }
1403                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1404                            >= Process.FIRST_APPLICATION_UID
1405                            && proc.pid != MY_PID);
1406                    for (int userId : mCurrentProfileIds) {
1407                        isBackground &= (proc.userId != userId);
1408                    }
1409                    if (isBackground && !showBackground) {
1410                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1411                        if (res != null) {
1412                            res.set(0);
1413                        }
1414                        return;
1415                    }
1416                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1417                        Dialog d = new AppErrorDialog(mContext,
1418                                ActivityManagerService.this, res, proc);
1419                        d.show();
1420                        proc.crashDialog = d;
1421                    } else {
1422                        // The device is asleep, so just pretend that the user
1423                        // saw a crash dialog and hit "force quit".
1424                        if (res != null) {
1425                            res.set(0);
1426                        }
1427                    }
1428                }
1429
1430                ensureBootCompleted();
1431            } break;
1432            case SHOW_NOT_RESPONDING_MSG: {
1433                synchronized (ActivityManagerService.this) {
1434                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1435                    ProcessRecord proc = (ProcessRecord)data.get("app");
1436                    if (proc != null && proc.anrDialog != null) {
1437                        Slog.e(TAG, "App already has anr dialog: " + proc);
1438                        return;
1439                    }
1440
1441                    Intent intent = new Intent("android.intent.action.ANR");
1442                    if (!mProcessesReady) {
1443                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1444                                | Intent.FLAG_RECEIVER_FOREGROUND);
1445                    }
1446                    broadcastIntentLocked(null, null, intent,
1447                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1448                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1449
1450                    if (mShowDialogs) {
1451                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1452                                mContext, proc, (ActivityRecord)data.get("activity"),
1453                                msg.arg1 != 0);
1454                        d.show();
1455                        proc.anrDialog = d;
1456                    } else {
1457                        // Just kill the app if there is no dialog to be shown.
1458                        killAppAtUsersRequest(proc, null);
1459                    }
1460                }
1461
1462                ensureBootCompleted();
1463            } break;
1464            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1465                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1466                synchronized (ActivityManagerService.this) {
1467                    ProcessRecord proc = (ProcessRecord) data.get("app");
1468                    if (proc == null) {
1469                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1470                        break;
1471                    }
1472                    if (proc.crashDialog != null) {
1473                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1474                        return;
1475                    }
1476                    AppErrorResult res = (AppErrorResult) data.get("result");
1477                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1478                        Dialog d = new StrictModeViolationDialog(mContext,
1479                                ActivityManagerService.this, res, proc);
1480                        d.show();
1481                        proc.crashDialog = d;
1482                    } else {
1483                        // The device is asleep, so just pretend that the user
1484                        // saw a crash dialog and hit "force quit".
1485                        res.set(0);
1486                    }
1487                }
1488                ensureBootCompleted();
1489            } break;
1490            case SHOW_FACTORY_ERROR_MSG: {
1491                Dialog d = new FactoryErrorDialog(
1492                    mContext, msg.getData().getCharSequence("msg"));
1493                d.show();
1494                ensureBootCompleted();
1495            } break;
1496            case WAIT_FOR_DEBUGGER_MSG: {
1497                synchronized (ActivityManagerService.this) {
1498                    ProcessRecord app = (ProcessRecord)msg.obj;
1499                    if (msg.arg1 != 0) {
1500                        if (!app.waitedForDebugger) {
1501                            Dialog d = new AppWaitingForDebuggerDialog(
1502                                    ActivityManagerService.this,
1503                                    mContext, app);
1504                            app.waitDialog = d;
1505                            app.waitedForDebugger = true;
1506                            d.show();
1507                        }
1508                    } else {
1509                        if (app.waitDialog != null) {
1510                            app.waitDialog.dismiss();
1511                            app.waitDialog = null;
1512                        }
1513                    }
1514                }
1515            } break;
1516            case SHOW_UID_ERROR_MSG: {
1517                if (mShowDialogs) {
1518                    AlertDialog d = new BaseErrorDialog(mContext);
1519                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1520                    d.setCancelable(false);
1521                    d.setTitle(mContext.getText(R.string.android_system_label));
1522                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1523                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1524                            obtainMessage(DISMISS_DIALOG_MSG, d));
1525                    d.show();
1526                }
1527            } break;
1528            case SHOW_FINGERPRINT_ERROR_MSG: {
1529                if (mShowDialogs) {
1530                    AlertDialog d = new BaseErrorDialog(mContext);
1531                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1532                    d.setCancelable(false);
1533                    d.setTitle(mContext.getText(R.string.android_system_label));
1534                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1535                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1536                            obtainMessage(DISMISS_DIALOG_MSG, d));
1537                    d.show();
1538                }
1539            } break;
1540            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1541                synchronized (ActivityManagerService.this) {
1542                    ActivityRecord ar = (ActivityRecord) msg.obj;
1543                    if (mCompatModeDialog != null) {
1544                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1545                                ar.info.applicationInfo.packageName)) {
1546                            return;
1547                        }
1548                        mCompatModeDialog.dismiss();
1549                        mCompatModeDialog = null;
1550                    }
1551                    if (ar != null && false) {
1552                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1553                                ar.packageName)) {
1554                            int mode = mCompatModePackages.computeCompatModeLocked(
1555                                    ar.info.applicationInfo);
1556                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1557                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1558                                mCompatModeDialog = new CompatModeDialog(
1559                                        ActivityManagerService.this, mContext,
1560                                        ar.info.applicationInfo);
1561                                mCompatModeDialog.show();
1562                            }
1563                        }
1564                    }
1565                }
1566                break;
1567            }
1568            case START_USER_SWITCH_MSG: {
1569                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1570                break;
1571            }
1572            case DISMISS_DIALOG_MSG: {
1573                final Dialog d = (Dialog) msg.obj;
1574                d.dismiss();
1575                break;
1576            }
1577            case DISPATCH_PROCESSES_CHANGED: {
1578                dispatchProcessesChanged();
1579                break;
1580            }
1581            case DISPATCH_PROCESS_DIED: {
1582                final int pid = msg.arg1;
1583                final int uid = msg.arg2;
1584                dispatchProcessDied(pid, uid);
1585                break;
1586            }
1587            case DISPATCH_UIDS_CHANGED_MSG: {
1588                dispatchUidsChanged();
1589            } break;
1590            }
1591        }
1592    }
1593
1594    final class MainHandler extends Handler {
1595        public MainHandler(Looper looper) {
1596            super(looper, null, true);
1597        }
1598
1599        @Override
1600        public void handleMessage(Message msg) {
1601            switch (msg.what) {
1602            case UPDATE_CONFIGURATION_MSG: {
1603                final ContentResolver resolver = mContext.getContentResolver();
1604                Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1605            } break;
1606            case GC_BACKGROUND_PROCESSES_MSG: {
1607                synchronized (ActivityManagerService.this) {
1608                    performAppGcsIfAppropriateLocked();
1609                }
1610            } break;
1611            case SERVICE_TIMEOUT_MSG: {
1612                if (mDidDexOpt) {
1613                    mDidDexOpt = false;
1614                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1615                    nmsg.obj = msg.obj;
1616                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1617                    return;
1618                }
1619                mServices.serviceTimeout((ProcessRecord)msg.obj);
1620            } break;
1621            case UPDATE_TIME_ZONE: {
1622                synchronized (ActivityManagerService.this) {
1623                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1624                        ProcessRecord r = mLruProcesses.get(i);
1625                        if (r.thread != null) {
1626                            try {
1627                                r.thread.updateTimeZone();
1628                            } catch (RemoteException ex) {
1629                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1630                            }
1631                        }
1632                    }
1633                }
1634            } break;
1635            case CLEAR_DNS_CACHE_MSG: {
1636                synchronized (ActivityManagerService.this) {
1637                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1638                        ProcessRecord r = mLruProcesses.get(i);
1639                        if (r.thread != null) {
1640                            try {
1641                                r.thread.clearDnsCache();
1642                            } catch (RemoteException ex) {
1643                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1644                            }
1645                        }
1646                    }
1647                }
1648            } break;
1649            case UPDATE_HTTP_PROXY_MSG: {
1650                ProxyInfo proxy = (ProxyInfo)msg.obj;
1651                String host = "";
1652                String port = "";
1653                String exclList = "";
1654                Uri pacFileUrl = Uri.EMPTY;
1655                if (proxy != null) {
1656                    host = proxy.getHost();
1657                    port = Integer.toString(proxy.getPort());
1658                    exclList = proxy.getExclusionListAsString();
1659                    pacFileUrl = proxy.getPacFileUrl();
1660                }
1661                synchronized (ActivityManagerService.this) {
1662                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1663                        ProcessRecord r = mLruProcesses.get(i);
1664                        if (r.thread != null) {
1665                            try {
1666                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1667                            } catch (RemoteException ex) {
1668                                Slog.w(TAG, "Failed to update http proxy for: " +
1669                                        r.info.processName);
1670                            }
1671                        }
1672                    }
1673                }
1674            } break;
1675            case PROC_START_TIMEOUT_MSG: {
1676                if (mDidDexOpt) {
1677                    mDidDexOpt = false;
1678                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1679                    nmsg.obj = msg.obj;
1680                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1681                    return;
1682                }
1683                ProcessRecord app = (ProcessRecord)msg.obj;
1684                synchronized (ActivityManagerService.this) {
1685                    processStartTimedOutLocked(app);
1686                }
1687            } break;
1688            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1689                synchronized (ActivityManagerService.this) {
1690                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1691                }
1692            } break;
1693            case KILL_APPLICATION_MSG: {
1694                synchronized (ActivityManagerService.this) {
1695                    int appid = msg.arg1;
1696                    boolean restart = (msg.arg2 == 1);
1697                    Bundle bundle = (Bundle)msg.obj;
1698                    String pkg = bundle.getString("pkg");
1699                    String reason = bundle.getString("reason");
1700                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1701                            false, UserHandle.USER_ALL, reason);
1702                }
1703            } break;
1704            case FINALIZE_PENDING_INTENT_MSG: {
1705                ((PendingIntentRecord)msg.obj).completeFinalize();
1706            } break;
1707            case POST_HEAVY_NOTIFICATION_MSG: {
1708                INotificationManager inm = NotificationManager.getService();
1709                if (inm == null) {
1710                    return;
1711                }
1712
1713                ActivityRecord root = (ActivityRecord)msg.obj;
1714                ProcessRecord process = root.app;
1715                if (process == null) {
1716                    return;
1717                }
1718
1719                try {
1720                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1721                    String text = mContext.getString(R.string.heavy_weight_notification,
1722                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1723                    Notification notification = new Notification.Builder(context)
1724                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1725                            .setWhen(0)
1726                            .setOngoing(true)
1727                            .setTicker(text)
1728                            .setColor(mContext.getColor(
1729                                    com.android.internal.R.color.system_notification_accent_color))
1730                            .setContentTitle(text)
1731                            .setContentText(
1732                                    mContext.getText(R.string.heavy_weight_notification_detail))
1733                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1734                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1735                                    new UserHandle(root.userId)))
1736                            .build();
1737                    try {
1738                        int[] outId = new int[1];
1739                        inm.enqueueNotificationWithTag("android", "android", null,
1740                                R.string.heavy_weight_notification,
1741                                notification, outId, root.userId);
1742                    } catch (RuntimeException e) {
1743                        Slog.w(ActivityManagerService.TAG,
1744                                "Error showing notification for heavy-weight app", e);
1745                    } catch (RemoteException e) {
1746                    }
1747                } catch (NameNotFoundException e) {
1748                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1749                }
1750            } break;
1751            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1752                INotificationManager inm = NotificationManager.getService();
1753                if (inm == null) {
1754                    return;
1755                }
1756                try {
1757                    inm.cancelNotificationWithTag("android", null,
1758                            R.string.heavy_weight_notification,  msg.arg1);
1759                } catch (RuntimeException e) {
1760                    Slog.w(ActivityManagerService.TAG,
1761                            "Error canceling notification for service", e);
1762                } catch (RemoteException e) {
1763                }
1764            } break;
1765            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1766                synchronized (ActivityManagerService.this) {
1767                    checkExcessivePowerUsageLocked(true);
1768                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1769                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1770                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1771                }
1772            } break;
1773            case REPORT_MEM_USAGE_MSG: {
1774                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1775                Thread thread = new Thread() {
1776                    @Override public void run() {
1777                        reportMemUsage(memInfos);
1778                    }
1779                };
1780                thread.start();
1781                break;
1782            }
1783            case REPORT_USER_SWITCH_MSG: {
1784                dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1785                break;
1786            }
1787            case CONTINUE_USER_SWITCH_MSG: {
1788                continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1789                break;
1790            }
1791            case USER_SWITCH_TIMEOUT_MSG: {
1792                timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1793                break;
1794            }
1795            case IMMERSIVE_MODE_LOCK_MSG: {
1796                final boolean nextState = (msg.arg1 != 0);
1797                if (mUpdateLock.isHeld() != nextState) {
1798                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1799                            "Applying new update lock state '" + nextState
1800                            + "' for " + (ActivityRecord)msg.obj);
1801                    if (nextState) {
1802                        mUpdateLock.acquire();
1803                    } else {
1804                        mUpdateLock.release();
1805                    }
1806                }
1807                break;
1808            }
1809            case PERSIST_URI_GRANTS_MSG: {
1810                writeGrantedUriPermissions();
1811                break;
1812            }
1813            case REQUEST_ALL_PSS_MSG: {
1814                synchronized (ActivityManagerService.this) {
1815                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1816                }
1817                break;
1818            }
1819            case START_PROFILES_MSG: {
1820                synchronized (ActivityManagerService.this) {
1821                    startProfilesLocked();
1822                }
1823                break;
1824            }
1825            case UPDATE_TIME: {
1826                synchronized (ActivityManagerService.this) {
1827                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1828                        ProcessRecord r = mLruProcesses.get(i);
1829                        if (r.thread != null) {
1830                            try {
1831                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1832                            } catch (RemoteException ex) {
1833                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1834                            }
1835                        }
1836                    }
1837                }
1838                break;
1839            }
1840            case SYSTEM_USER_START_MSG: {
1841                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1842                        Integer.toString(msg.arg1), msg.arg1);
1843                mSystemServiceManager.startUser(msg.arg1);
1844                break;
1845            }
1846            case SYSTEM_USER_CURRENT_MSG: {
1847                mBatteryStatsService.noteEvent(
1848                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1849                        Integer.toString(msg.arg2), msg.arg2);
1850                mBatteryStatsService.noteEvent(
1851                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1852                        Integer.toString(msg.arg1), msg.arg1);
1853                mSystemServiceManager.switchUser(msg.arg1);
1854                break;
1855            }
1856            case ENTER_ANIMATION_COMPLETE_MSG: {
1857                synchronized (ActivityManagerService.this) {
1858                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1859                    if (r != null && r.app != null && r.app.thread != null) {
1860                        try {
1861                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1862                        } catch (RemoteException e) {
1863                        }
1864                    }
1865                }
1866                break;
1867            }
1868            case FINISH_BOOTING_MSG: {
1869                if (msg.arg1 != 0) {
1870                    finishBooting();
1871                }
1872                if (msg.arg2 != 0) {
1873                    enableScreenAfterBoot();
1874                }
1875                break;
1876            }
1877            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1878                try {
1879                    Locale l = (Locale) msg.obj;
1880                    IBinder service = ServiceManager.getService("mount");
1881                    IMountService mountService = IMountService.Stub.asInterface(service);
1882                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1883                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1884                } catch (RemoteException e) {
1885                    Log.e(TAG, "Error storing locale for decryption UI", e);
1886                }
1887                break;
1888            }
1889            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1890                synchronized (ActivityManagerService.this) {
1891                    int i = mTaskStackListeners.beginBroadcast();
1892                    while (i > 0) {
1893                        i--;
1894                        try {
1895                            // Make a one-way callback to the listener
1896                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1897                        } catch (RemoteException e){
1898                            // Handled by the RemoteCallbackList
1899                        }
1900                    }
1901                    mTaskStackListeners.finishBroadcast();
1902                }
1903                break;
1904            }
1905            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1906                final int uid = msg.arg1;
1907                final byte[] firstPacket = (byte[]) msg.obj;
1908
1909                synchronized (mPidsSelfLocked) {
1910                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1911                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1912                        if (p.uid == uid) {
1913                            try {
1914                                p.thread.notifyCleartextNetwork(firstPacket);
1915                            } catch (RemoteException ignored) {
1916                            }
1917                        }
1918                    }
1919                }
1920                break;
1921            }
1922            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1923                final String procName;
1924                final int uid;
1925                final long memLimit;
1926                final String reportPackage;
1927                synchronized (ActivityManagerService.this) {
1928                    procName = mMemWatchDumpProcName;
1929                    uid = mMemWatchDumpUid;
1930                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1931                    if (val == null) {
1932                        val = mMemWatchProcesses.get(procName, 0);
1933                    }
1934                    if (val != null) {
1935                        memLimit = val.first;
1936                        reportPackage = val.second;
1937                    } else {
1938                        memLimit = 0;
1939                        reportPackage = null;
1940                    }
1941                }
1942                if (procName == null) {
1943                    return;
1944                }
1945
1946                if (DEBUG_PSS) Slog.d(TAG_PSS,
1947                        "Showing dump heap notification from " + procName + "/" + uid);
1948
1949                INotificationManager inm = NotificationManager.getService();
1950                if (inm == null) {
1951                    return;
1952                }
1953
1954                String text = mContext.getString(R.string.dump_heap_notification, procName);
1955
1956
1957                Intent deleteIntent = new Intent();
1958                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1959                Intent intent = new Intent();
1960                intent.setClassName("android", DumpHeapActivity.class.getName());
1961                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1962                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1963                if (reportPackage != null) {
1964                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1965                }
1966                int userId = UserHandle.getUserId(uid);
1967                Notification notification = new Notification.Builder(mContext)
1968                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1969                        .setWhen(0)
1970                        .setOngoing(true)
1971                        .setAutoCancel(true)
1972                        .setTicker(text)
1973                        .setColor(mContext.getColor(
1974                                com.android.internal.R.color.system_notification_accent_color))
1975                        .setContentTitle(text)
1976                        .setContentText(
1977                                mContext.getText(R.string.dump_heap_notification_detail))
1978                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1979                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1980                                new UserHandle(userId)))
1981                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
1982                                deleteIntent, 0, UserHandle.OWNER))
1983                        .build();
1984
1985                try {
1986                    int[] outId = new int[1];
1987                    inm.enqueueNotificationWithTag("android", "android", null,
1988                            R.string.dump_heap_notification,
1989                            notification, outId, userId);
1990                } catch (RuntimeException e) {
1991                    Slog.w(ActivityManagerService.TAG,
1992                            "Error showing notification for dump heap", e);
1993                } catch (RemoteException e) {
1994                }
1995            } break;
1996            case DELETE_DUMPHEAP_MSG: {
1997                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
1998                        DumpHeapActivity.JAVA_URI,
1999                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2000                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2001                        UserHandle.myUserId());
2002                synchronized (ActivityManagerService.this) {
2003                    mMemWatchDumpFile = null;
2004                    mMemWatchDumpProcName = null;
2005                    mMemWatchDumpPid = -1;
2006                    mMemWatchDumpUid = -1;
2007                }
2008            } break;
2009            case FOREGROUND_PROFILE_CHANGED_MSG: {
2010                dispatchForegroundProfileChanged(msg.arg1);
2011            } break;
2012            case REPORT_TIME_TRACKER_MSG: {
2013                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2014                tracker.deliverResult(mContext);
2015            } break;
2016            }
2017        }
2018    };
2019
2020    static final int COLLECT_PSS_BG_MSG = 1;
2021
2022    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2023        @Override
2024        public void handleMessage(Message msg) {
2025            switch (msg.what) {
2026            case COLLECT_PSS_BG_MSG: {
2027                long start = SystemClock.uptimeMillis();
2028                MemInfoReader memInfo = null;
2029                synchronized (ActivityManagerService.this) {
2030                    if (mFullPssPending) {
2031                        mFullPssPending = false;
2032                        memInfo = new MemInfoReader();
2033                    }
2034                }
2035                if (memInfo != null) {
2036                    updateCpuStatsNow();
2037                    long nativeTotalPss = 0;
2038                    synchronized (mProcessCpuTracker) {
2039                        final int N = mProcessCpuTracker.countStats();
2040                        for (int j=0; j<N; j++) {
2041                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2042                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2043                                // This is definitely an application process; skip it.
2044                                continue;
2045                            }
2046                            synchronized (mPidsSelfLocked) {
2047                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2048                                    // This is one of our own processes; skip it.
2049                                    continue;
2050                                }
2051                            }
2052                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2053                        }
2054                    }
2055                    memInfo.readMemInfo();
2056                    synchronized (ActivityManagerService.this) {
2057                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2058                                + (SystemClock.uptimeMillis()-start) + "ms");
2059                        final long cachedKb = memInfo.getCachedSizeKb();
2060                        final long freeKb = memInfo.getFreeSizeKb();
2061                        final long zramKb = memInfo.getZramTotalSizeKb();
2062                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2063                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2064                                kernelKb*1024, nativeTotalPss*1024);
2065                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2066                                nativeTotalPss);
2067                    }
2068                }
2069
2070                int num = 0;
2071                long[] tmp = new long[1];
2072                do {
2073                    ProcessRecord proc;
2074                    int procState;
2075                    int pid;
2076                    long lastPssTime;
2077                    synchronized (ActivityManagerService.this) {
2078                        if (mPendingPssProcesses.size() <= 0) {
2079                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2080                                    "Collected PSS of " + num + " processes in "
2081                                    + (SystemClock.uptimeMillis() - start) + "ms");
2082                            mPendingPssProcesses.clear();
2083                            return;
2084                        }
2085                        proc = mPendingPssProcesses.remove(0);
2086                        procState = proc.pssProcState;
2087                        lastPssTime = proc.lastPssTime;
2088                        if (proc.thread != null && procState == proc.setProcState
2089                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2090                                        < SystemClock.uptimeMillis()) {
2091                            pid = proc.pid;
2092                        } else {
2093                            proc = null;
2094                            pid = 0;
2095                        }
2096                    }
2097                    if (proc != null) {
2098                        long pss = Debug.getPss(pid, tmp, null);
2099                        synchronized (ActivityManagerService.this) {
2100                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2101                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2102                                num++;
2103                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2104                                        SystemClock.uptimeMillis());
2105                            }
2106                        }
2107                    }
2108                } while (true);
2109            }
2110            }
2111        }
2112    };
2113
2114    public void setSystemProcess() {
2115        try {
2116            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2117            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2118            ServiceManager.addService("meminfo", new MemBinder(this));
2119            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2120            ServiceManager.addService("dbinfo", new DbBinder(this));
2121            if (MONITOR_CPU_USAGE) {
2122                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2123            }
2124            ServiceManager.addService("permission", new PermissionController(this));
2125            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2126
2127            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2128                    "android", STOCK_PM_FLAGS);
2129            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2130
2131            synchronized (this) {
2132                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2133                app.persistent = true;
2134                app.pid = MY_PID;
2135                app.maxAdj = ProcessList.SYSTEM_ADJ;
2136                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2137                synchronized (mPidsSelfLocked) {
2138                    mPidsSelfLocked.put(app.pid, app);
2139                }
2140                updateLruProcessLocked(app, false, null);
2141                updateOomAdjLocked();
2142            }
2143        } catch (PackageManager.NameNotFoundException e) {
2144            throw new RuntimeException(
2145                    "Unable to find android system package", e);
2146        }
2147    }
2148
2149    public void setWindowManager(WindowManagerService wm) {
2150        mWindowManager = wm;
2151        mStackSupervisor.setWindowManager(wm);
2152    }
2153
2154    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2155        mUsageStatsService = usageStatsManager;
2156    }
2157
2158    public void startObservingNativeCrashes() {
2159        final NativeCrashListener ncl = new NativeCrashListener(this);
2160        ncl.start();
2161    }
2162
2163    public IAppOpsService getAppOpsService() {
2164        return mAppOpsService;
2165    }
2166
2167    static class MemBinder extends Binder {
2168        ActivityManagerService mActivityManagerService;
2169        MemBinder(ActivityManagerService activityManagerService) {
2170            mActivityManagerService = activityManagerService;
2171        }
2172
2173        @Override
2174        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2175            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2176                    != PackageManager.PERMISSION_GRANTED) {
2177                pw.println("Permission Denial: can't dump meminfo from from pid="
2178                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2179                        + " without permission " + android.Manifest.permission.DUMP);
2180                return;
2181            }
2182
2183            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2184        }
2185    }
2186
2187    static class GraphicsBinder extends Binder {
2188        ActivityManagerService mActivityManagerService;
2189        GraphicsBinder(ActivityManagerService activityManagerService) {
2190            mActivityManagerService = activityManagerService;
2191        }
2192
2193        @Override
2194        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2195            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2196                    != PackageManager.PERMISSION_GRANTED) {
2197                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2198                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2199                        + " without permission " + android.Manifest.permission.DUMP);
2200                return;
2201            }
2202
2203            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2204        }
2205    }
2206
2207    static class DbBinder extends Binder {
2208        ActivityManagerService mActivityManagerService;
2209        DbBinder(ActivityManagerService activityManagerService) {
2210            mActivityManagerService = activityManagerService;
2211        }
2212
2213        @Override
2214        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2215            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2216                    != PackageManager.PERMISSION_GRANTED) {
2217                pw.println("Permission Denial: can't dump dbinfo from from pid="
2218                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2219                        + " without permission " + android.Manifest.permission.DUMP);
2220                return;
2221            }
2222
2223            mActivityManagerService.dumpDbInfo(fd, pw, args);
2224        }
2225    }
2226
2227    static class CpuBinder extends Binder {
2228        ActivityManagerService mActivityManagerService;
2229        CpuBinder(ActivityManagerService activityManagerService) {
2230            mActivityManagerService = activityManagerService;
2231        }
2232
2233        @Override
2234        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2235            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2236                    != PackageManager.PERMISSION_GRANTED) {
2237                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2238                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2239                        + " without permission " + android.Manifest.permission.DUMP);
2240                return;
2241            }
2242
2243            synchronized (mActivityManagerService.mProcessCpuTracker) {
2244                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2245                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2246                        SystemClock.uptimeMillis()));
2247            }
2248        }
2249    }
2250
2251    public static final class Lifecycle extends SystemService {
2252        private final ActivityManagerService mService;
2253
2254        public Lifecycle(Context context) {
2255            super(context);
2256            mService = new ActivityManagerService(context);
2257        }
2258
2259        @Override
2260        public void onStart() {
2261            mService.start();
2262        }
2263
2264        public ActivityManagerService getService() {
2265            return mService;
2266        }
2267    }
2268
2269    // Note: This method is invoked on the main thread but may need to attach various
2270    // handlers to other threads.  So take care to be explicit about the looper.
2271    public ActivityManagerService(Context systemContext) {
2272        mContext = systemContext;
2273        mFactoryTest = FactoryTest.getMode();
2274        mSystemThread = ActivityThread.currentActivityThread();
2275
2276        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2277
2278        mHandlerThread = new ServiceThread(TAG,
2279                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2280        mHandlerThread.start();
2281        mHandler = new MainHandler(mHandlerThread.getLooper());
2282        mUiHandler = new UiHandler();
2283
2284        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2285                "foreground", BROADCAST_FG_TIMEOUT, false);
2286        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2287                "background", BROADCAST_BG_TIMEOUT, true);
2288        mBroadcastQueues[0] = mFgBroadcastQueue;
2289        mBroadcastQueues[1] = mBgBroadcastQueue;
2290
2291        mServices = new ActiveServices(this);
2292        mProviderMap = new ProviderMap(this);
2293
2294        // TODO: Move creation of battery stats service outside of activity manager service.
2295        File dataDir = Environment.getDataDirectory();
2296        File systemDir = new File(dataDir, "system");
2297        systemDir.mkdirs();
2298        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2299        mBatteryStatsService.getActiveStatistics().readLocked();
2300        mBatteryStatsService.scheduleWriteToDisk();
2301        mOnBattery = DEBUG_POWER ? true
2302                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2303        mBatteryStatsService.getActiveStatistics().setCallback(this);
2304
2305        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2306
2307        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2308
2309        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2310
2311        // User 0 is the first and only user that runs at boot.
2312        mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2313        mUserLru.add(UserHandle.USER_OWNER);
2314        updateStartedUserArrayLocked();
2315
2316        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2317            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2318
2319        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2320
2321        mConfiguration.setToDefaults();
2322        mConfiguration.setLocale(Locale.getDefault());
2323
2324        mConfigurationSeq = mConfiguration.seq = 1;
2325        mProcessCpuTracker.init();
2326
2327        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2328        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2329        mRecentTasks = new RecentTasks(this);
2330        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2331        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2332
2333        mProcessCpuThread = new Thread("CpuTracker") {
2334            @Override
2335            public void run() {
2336                while (true) {
2337                    try {
2338                        try {
2339                            synchronized(this) {
2340                                final long now = SystemClock.uptimeMillis();
2341                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2342                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2343                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2344                                //        + ", write delay=" + nextWriteDelay);
2345                                if (nextWriteDelay < nextCpuDelay) {
2346                                    nextCpuDelay = nextWriteDelay;
2347                                }
2348                                if (nextCpuDelay > 0) {
2349                                    mProcessCpuMutexFree.set(true);
2350                                    this.wait(nextCpuDelay);
2351                                }
2352                            }
2353                        } catch (InterruptedException e) {
2354                        }
2355                        updateCpuStatsNow();
2356                    } catch (Exception e) {
2357                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2358                    }
2359                }
2360            }
2361        };
2362
2363        Watchdog.getInstance().addMonitor(this);
2364        Watchdog.getInstance().addThread(mHandler);
2365    }
2366
2367    public void setSystemServiceManager(SystemServiceManager mgr) {
2368        mSystemServiceManager = mgr;
2369    }
2370
2371    public void setInstaller(Installer installer) {
2372        mInstaller = installer;
2373    }
2374
2375    private void start() {
2376        Process.removeAllProcessGroups();
2377        mProcessCpuThread.start();
2378
2379        mBatteryStatsService.publish(mContext);
2380        mAppOpsService.publish(mContext);
2381        Slog.d("AppOps", "AppOpsService published");
2382        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2383    }
2384
2385    public void initPowerManagement() {
2386        mStackSupervisor.initPowerManagement();
2387        mBatteryStatsService.initPowerManagement();
2388        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2389        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2390        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2391        mVoiceWakeLock.setReferenceCounted(false);
2392    }
2393
2394    @Override
2395    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2396            throws RemoteException {
2397        if (code == SYSPROPS_TRANSACTION) {
2398            // We need to tell all apps about the system property change.
2399            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2400            synchronized(this) {
2401                final int NP = mProcessNames.getMap().size();
2402                for (int ip=0; ip<NP; ip++) {
2403                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2404                    final int NA = apps.size();
2405                    for (int ia=0; ia<NA; ia++) {
2406                        ProcessRecord app = apps.valueAt(ia);
2407                        if (app.thread != null) {
2408                            procs.add(app.thread.asBinder());
2409                        }
2410                    }
2411                }
2412            }
2413
2414            int N = procs.size();
2415            for (int i=0; i<N; i++) {
2416                Parcel data2 = Parcel.obtain();
2417                try {
2418                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2419                } catch (RemoteException e) {
2420                }
2421                data2.recycle();
2422            }
2423        }
2424        try {
2425            return super.onTransact(code, data, reply, flags);
2426        } catch (RuntimeException e) {
2427            // The activity manager only throws security exceptions, so let's
2428            // log all others.
2429            if (!(e instanceof SecurityException)) {
2430                Slog.wtf(TAG, "Activity Manager Crash", e);
2431            }
2432            throw e;
2433        }
2434    }
2435
2436    void updateCpuStats() {
2437        final long now = SystemClock.uptimeMillis();
2438        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2439            return;
2440        }
2441        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2442            synchronized (mProcessCpuThread) {
2443                mProcessCpuThread.notify();
2444            }
2445        }
2446    }
2447
2448    void updateCpuStatsNow() {
2449        synchronized (mProcessCpuTracker) {
2450            mProcessCpuMutexFree.set(false);
2451            final long now = SystemClock.uptimeMillis();
2452            boolean haveNewCpuStats = false;
2453
2454            if (MONITOR_CPU_USAGE &&
2455                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2456                mLastCpuTime.set(now);
2457                mProcessCpuTracker.update();
2458                if (mProcessCpuTracker.hasGoodLastStats()) {
2459                    haveNewCpuStats = true;
2460                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2461                    //Slog.i(TAG, "Total CPU usage: "
2462                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2463
2464                    // Slog the cpu usage if the property is set.
2465                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2466                        int user = mProcessCpuTracker.getLastUserTime();
2467                        int system = mProcessCpuTracker.getLastSystemTime();
2468                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2469                        int irq = mProcessCpuTracker.getLastIrqTime();
2470                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2471                        int idle = mProcessCpuTracker.getLastIdleTime();
2472
2473                        int total = user + system + iowait + irq + softIrq + idle;
2474                        if (total == 0) total = 1;
2475
2476                        EventLog.writeEvent(EventLogTags.CPU,
2477                                ((user+system+iowait+irq+softIrq) * 100) / total,
2478                                (user * 100) / total,
2479                                (system * 100) / total,
2480                                (iowait * 100) / total,
2481                                (irq * 100) / total,
2482                                (softIrq * 100) / total);
2483                    }
2484                }
2485            }
2486
2487            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2488            synchronized(bstats) {
2489                synchronized(mPidsSelfLocked) {
2490                    if (haveNewCpuStats) {
2491                        final int perc = bstats.startAddingCpuLocked();
2492                        if (perc >= 0) {
2493                            int remainUTime = 0;
2494                            int remainSTime = 0;
2495                            int totalUTime = 0;
2496                            int totalSTime = 0;
2497                            final int N = mProcessCpuTracker.countStats();
2498                            for (int i=0; i<N; i++) {
2499                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2500                                if (!st.working) {
2501                                    continue;
2502                                }
2503                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2504                                int otherUTime = (st.rel_utime*perc)/100;
2505                                int otherSTime = (st.rel_stime*perc)/100;
2506                                remainUTime += otherUTime;
2507                                remainSTime += otherSTime;
2508                                totalUTime += st.rel_utime;
2509                                totalSTime += st.rel_stime;
2510                                if (pr != null) {
2511                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2512                                    if (ps == null || !ps.isActive()) {
2513                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2514                                                pr.info.uid, pr.processName);
2515                                    }
2516                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2517                                            st.rel_stime - otherSTime);
2518                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2519                                } else {
2520                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2521                                    if (ps == null || !ps.isActive()) {
2522                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2523                                                bstats.mapUid(st.uid), st.name);
2524                                    }
2525                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2526                                            st.rel_stime - otherSTime);
2527                                }
2528                            }
2529                            final int userTime = mProcessCpuTracker.getLastUserTime();
2530                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2531                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2532                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2533                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2534                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2535                            bstats.finishAddingCpuLocked(perc, remainUTime,
2536                                    remainSTime, totalUTime, totalSTime, userTime, systemTime,
2537                                    iowaitTime, irqTime, softIrqTime, idleTime);
2538                        }
2539                    }
2540                }
2541
2542                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2543                    mLastWriteTime = now;
2544                    mBatteryStatsService.scheduleWriteToDisk();
2545                }
2546            }
2547        }
2548    }
2549
2550    @Override
2551    public void batteryNeedsCpuUpdate() {
2552        updateCpuStatsNow();
2553    }
2554
2555    @Override
2556    public void batteryPowerChanged(boolean onBattery) {
2557        // When plugging in, update the CPU stats first before changing
2558        // the plug state.
2559        updateCpuStatsNow();
2560        synchronized (this) {
2561            synchronized(mPidsSelfLocked) {
2562                mOnBattery = DEBUG_POWER ? true : onBattery;
2563            }
2564        }
2565    }
2566
2567    @Override
2568    public void batterySendBroadcast(Intent intent) {
2569        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2570                AppOpsManager.OP_NONE, null, false, false,
2571                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2572    }
2573
2574    /**
2575     * Initialize the application bind args. These are passed to each
2576     * process when the bindApplication() IPC is sent to the process. They're
2577     * lazily setup to make sure the services are running when they're asked for.
2578     */
2579    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2580        if (mAppBindArgs == null) {
2581            mAppBindArgs = new HashMap<>();
2582
2583            // Isolated processes won't get this optimization, so that we don't
2584            // violate the rules about which services they have access to.
2585            if (!isolated) {
2586                // Setup the application init args
2587                mAppBindArgs.put("package", ServiceManager.getService("package"));
2588                mAppBindArgs.put("window", ServiceManager.getService("window"));
2589                mAppBindArgs.put(Context.ALARM_SERVICE,
2590                        ServiceManager.getService(Context.ALARM_SERVICE));
2591            }
2592        }
2593        return mAppBindArgs;
2594    }
2595
2596    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2597        if (r != null && mFocusedActivity != r) {
2598            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2599            ActivityRecord last = mFocusedActivity;
2600            mFocusedActivity = r;
2601            if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2602                    && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2603                if (mCurAppTimeTracker != r.appTimeTracker) {
2604                    // We are switching app tracking.  Complete the current one.
2605                    if (mCurAppTimeTracker != null) {
2606                        mCurAppTimeTracker.stop();
2607                        mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2608                                mCurAppTimeTracker).sendToTarget();
2609                        mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2610                        mCurAppTimeTracker = null;
2611                    }
2612                    if (r.appTimeTracker != null) {
2613                        mCurAppTimeTracker = r.appTimeTracker;
2614                        startTimeTrackingFocusedActivityLocked();
2615                    }
2616                } else {
2617                    startTimeTrackingFocusedActivityLocked();
2618                }
2619            } else {
2620                r.appTimeTracker = null;
2621            }
2622            if (r.task != null && r.task.voiceInteractor != null) {
2623                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2624            } else {
2625                finishRunningVoiceLocked();
2626                if (last != null && last.task.voiceSession != null) {
2627                    // We had been in a voice interaction session, but now focused has
2628                    // move to something different.  Just finish the session, we can't
2629                    // return to it and retain the proper state and synchronization with
2630                    // the voice interaction service.
2631                    finishVoiceTask(last.task.voiceSession);
2632                }
2633            }
2634            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2635                mWindowManager.setFocusedApp(r.appToken, true);
2636            }
2637            applyUpdateLockStateLocked(r);
2638            if (mFocusedActivity.userId != mLastFocusedUserId) {
2639                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2640                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2641                        mFocusedActivity.userId, 0));
2642                mLastFocusedUserId = mFocusedActivity.userId;
2643            }
2644        }
2645        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2646                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2647                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2648    }
2649
2650    final void clearFocusedActivity(ActivityRecord r) {
2651        if (mFocusedActivity == r) {
2652            ActivityStack stack = mStackSupervisor.getFocusedStack();
2653            if (stack != null) {
2654                ActivityRecord top = stack.topActivity();
2655                if (top != null && top.userId != mLastFocusedUserId) {
2656                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2657                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2658                                    top.userId, 0));
2659                    mLastFocusedUserId = top.userId;
2660                }
2661            }
2662            mFocusedActivity = null;
2663            EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2664        }
2665    }
2666
2667    @Override
2668    public void setFocusedStack(int stackId) {
2669        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2670        synchronized (ActivityManagerService.this) {
2671            ActivityStack stack = mStackSupervisor.getStack(stackId);
2672            if (stack != null) {
2673                ActivityRecord r = stack.topRunningActivityLocked(null);
2674                if (r != null) {
2675                    setFocusedActivityLocked(r, "setFocusedStack");
2676                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2677                }
2678            }
2679        }
2680    }
2681
2682    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2683    @Override
2684    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2685        synchronized (ActivityManagerService.this) {
2686            if (listener != null) {
2687                mTaskStackListeners.register(listener);
2688            }
2689        }
2690    }
2691
2692    @Override
2693    public void notifyActivityDrawn(IBinder token) {
2694        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2695        synchronized (this) {
2696            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2697            if (r != null) {
2698                r.task.stack.notifyActivityDrawnLocked(r);
2699            }
2700        }
2701    }
2702
2703    final void applyUpdateLockStateLocked(ActivityRecord r) {
2704        // Modifications to the UpdateLock state are done on our handler, outside
2705        // the activity manager's locks.  The new state is determined based on the
2706        // state *now* of the relevant activity record.  The object is passed to
2707        // the handler solely for logging detail, not to be consulted/modified.
2708        final boolean nextState = r != null && r.immersive;
2709        mHandler.sendMessage(
2710                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2711    }
2712
2713    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2714        Message msg = Message.obtain();
2715        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2716        msg.obj = r.task.askedCompatMode ? null : r;
2717        mUiHandler.sendMessage(msg);
2718    }
2719
2720    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2721            String what, Object obj, ProcessRecord srcApp) {
2722        app.lastActivityTime = now;
2723
2724        if (app.activities.size() > 0) {
2725            // Don't want to touch dependent processes that are hosting activities.
2726            return index;
2727        }
2728
2729        int lrui = mLruProcesses.lastIndexOf(app);
2730        if (lrui < 0) {
2731            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2732                    + what + " " + obj + " from " + srcApp);
2733            return index;
2734        }
2735
2736        if (lrui >= index) {
2737            // Don't want to cause this to move dependent processes *back* in the
2738            // list as if they were less frequently used.
2739            return index;
2740        }
2741
2742        if (lrui >= mLruProcessActivityStart) {
2743            // Don't want to touch dependent processes that are hosting activities.
2744            return index;
2745        }
2746
2747        mLruProcesses.remove(lrui);
2748        if (index > 0) {
2749            index--;
2750        }
2751        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2752                + " in LRU list: " + app);
2753        mLruProcesses.add(index, app);
2754        return index;
2755    }
2756
2757    final void removeLruProcessLocked(ProcessRecord app) {
2758        int lrui = mLruProcesses.lastIndexOf(app);
2759        if (lrui >= 0) {
2760            if (!app.killed) {
2761                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2762                Process.killProcessQuiet(app.pid);
2763                Process.killProcessGroup(app.info.uid, app.pid);
2764            }
2765            if (lrui <= mLruProcessActivityStart) {
2766                mLruProcessActivityStart--;
2767            }
2768            if (lrui <= mLruProcessServiceStart) {
2769                mLruProcessServiceStart--;
2770            }
2771            mLruProcesses.remove(lrui);
2772        }
2773    }
2774
2775    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2776            ProcessRecord client) {
2777        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2778                || app.treatLikeActivity;
2779        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2780        if (!activityChange && hasActivity) {
2781            // The process has activities, so we are only allowing activity-based adjustments
2782            // to move it.  It should be kept in the front of the list with other
2783            // processes that have activities, and we don't want those to change their
2784            // order except due to activity operations.
2785            return;
2786        }
2787
2788        mLruSeq++;
2789        final long now = SystemClock.uptimeMillis();
2790        app.lastActivityTime = now;
2791
2792        // First a quick reject: if the app is already at the position we will
2793        // put it, then there is nothing to do.
2794        if (hasActivity) {
2795            final int N = mLruProcesses.size();
2796            if (N > 0 && mLruProcesses.get(N-1) == app) {
2797                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2798                return;
2799            }
2800        } else {
2801            if (mLruProcessServiceStart > 0
2802                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2803                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2804                return;
2805            }
2806        }
2807
2808        int lrui = mLruProcesses.lastIndexOf(app);
2809
2810        if (app.persistent && lrui >= 0) {
2811            // We don't care about the position of persistent processes, as long as
2812            // they are in the list.
2813            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2814            return;
2815        }
2816
2817        /* In progress: compute new position first, so we can avoid doing work
2818           if the process is not actually going to move.  Not yet working.
2819        int addIndex;
2820        int nextIndex;
2821        boolean inActivity = false, inService = false;
2822        if (hasActivity) {
2823            // Process has activities, put it at the very tipsy-top.
2824            addIndex = mLruProcesses.size();
2825            nextIndex = mLruProcessServiceStart;
2826            inActivity = true;
2827        } else if (hasService) {
2828            // Process has services, put it at the top of the service list.
2829            addIndex = mLruProcessActivityStart;
2830            nextIndex = mLruProcessServiceStart;
2831            inActivity = true;
2832            inService = true;
2833        } else  {
2834            // Process not otherwise of interest, it goes to the top of the non-service area.
2835            addIndex = mLruProcessServiceStart;
2836            if (client != null) {
2837                int clientIndex = mLruProcesses.lastIndexOf(client);
2838                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2839                        + app);
2840                if (clientIndex >= 0 && addIndex > clientIndex) {
2841                    addIndex = clientIndex;
2842                }
2843            }
2844            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2845        }
2846
2847        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2848                + mLruProcessActivityStart + "): " + app);
2849        */
2850
2851        if (lrui >= 0) {
2852            if (lrui < mLruProcessActivityStart) {
2853                mLruProcessActivityStart--;
2854            }
2855            if (lrui < mLruProcessServiceStart) {
2856                mLruProcessServiceStart--;
2857            }
2858            /*
2859            if (addIndex > lrui) {
2860                addIndex--;
2861            }
2862            if (nextIndex > lrui) {
2863                nextIndex--;
2864            }
2865            */
2866            mLruProcesses.remove(lrui);
2867        }
2868
2869        /*
2870        mLruProcesses.add(addIndex, app);
2871        if (inActivity) {
2872            mLruProcessActivityStart++;
2873        }
2874        if (inService) {
2875            mLruProcessActivityStart++;
2876        }
2877        */
2878
2879        int nextIndex;
2880        if (hasActivity) {
2881            final int N = mLruProcesses.size();
2882            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2883                // Process doesn't have activities, but has clients with
2884                // activities...  move it up, but one below the top (the top
2885                // should always have a real activity).
2886                if (DEBUG_LRU) Slog.d(TAG_LRU,
2887                        "Adding to second-top of LRU activity list: " + app);
2888                mLruProcesses.add(N - 1, app);
2889                // To keep it from spamming the LRU list (by making a bunch of clients),
2890                // we will push down any other entries owned by the app.
2891                final int uid = app.info.uid;
2892                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2893                    ProcessRecord subProc = mLruProcesses.get(i);
2894                    if (subProc.info.uid == uid) {
2895                        // We want to push this one down the list.  If the process after
2896                        // it is for the same uid, however, don't do so, because we don't
2897                        // want them internally to be re-ordered.
2898                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2899                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2900                                    "Pushing uid " + uid + " swapping at " + i + ": "
2901                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2902                            ProcessRecord tmp = mLruProcesses.get(i);
2903                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2904                            mLruProcesses.set(i - 1, tmp);
2905                            i--;
2906                        }
2907                    } else {
2908                        // A gap, we can stop here.
2909                        break;
2910                    }
2911                }
2912            } else {
2913                // Process has activities, put it at the very tipsy-top.
2914                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2915                mLruProcesses.add(app);
2916            }
2917            nextIndex = mLruProcessServiceStart;
2918        } else if (hasService) {
2919            // Process has services, put it at the top of the service list.
2920            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2921            mLruProcesses.add(mLruProcessActivityStart, app);
2922            nextIndex = mLruProcessServiceStart;
2923            mLruProcessActivityStart++;
2924        } else  {
2925            // Process not otherwise of interest, it goes to the top of the non-service area.
2926            int index = mLruProcessServiceStart;
2927            if (client != null) {
2928                // If there is a client, don't allow the process to be moved up higher
2929                // in the list than that client.
2930                int clientIndex = mLruProcesses.lastIndexOf(client);
2931                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2932                        + " when updating " + app);
2933                if (clientIndex <= lrui) {
2934                    // Don't allow the client index restriction to push it down farther in the
2935                    // list than it already is.
2936                    clientIndex = lrui;
2937                }
2938                if (clientIndex >= 0 && index > clientIndex) {
2939                    index = clientIndex;
2940                }
2941            }
2942            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2943            mLruProcesses.add(index, app);
2944            nextIndex = index-1;
2945            mLruProcessActivityStart++;
2946            mLruProcessServiceStart++;
2947        }
2948
2949        // If the app is currently using a content provider or service,
2950        // bump those processes as well.
2951        for (int j=app.connections.size()-1; j>=0; j--) {
2952            ConnectionRecord cr = app.connections.valueAt(j);
2953            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2954                    && cr.binding.service.app != null
2955                    && cr.binding.service.app.lruSeq != mLruSeq
2956                    && !cr.binding.service.app.persistent) {
2957                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2958                        "service connection", cr, app);
2959            }
2960        }
2961        for (int j=app.conProviders.size()-1; j>=0; j--) {
2962            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2963            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2964                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2965                        "provider reference", cpr, app);
2966            }
2967        }
2968    }
2969
2970    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2971        if (uid == Process.SYSTEM_UID) {
2972            // The system gets to run in any process.  If there are multiple
2973            // processes with the same uid, just pick the first (this
2974            // should never happen).
2975            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2976            if (procs == null) return null;
2977            final int procCount = procs.size();
2978            for (int i = 0; i < procCount; i++) {
2979                final int procUid = procs.keyAt(i);
2980                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
2981                    // Don't use an app process or different user process for system component.
2982                    continue;
2983                }
2984                return procs.valueAt(i);
2985            }
2986        }
2987        ProcessRecord proc = mProcessNames.get(processName, uid);
2988        if (false && proc != null && !keepIfLarge
2989                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2990                && proc.lastCachedPss >= 4000) {
2991            // Turn this condition on to cause killing to happen regularly, for testing.
2992            if (proc.baseProcessTracker != null) {
2993                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2994            }
2995            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2996        } else if (proc != null && !keepIfLarge
2997                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2998                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2999            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3000            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3001                if (proc.baseProcessTracker != null) {
3002                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3003                }
3004                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3005            }
3006        }
3007        return proc;
3008    }
3009
3010    void ensurePackageDexOpt(String packageName) {
3011        IPackageManager pm = AppGlobals.getPackageManager();
3012        try {
3013            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3014                mDidDexOpt = true;
3015            }
3016        } catch (RemoteException e) {
3017        }
3018    }
3019
3020    boolean isNextTransitionForward() {
3021        int transit = mWindowManager.getPendingAppTransition();
3022        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3023                || transit == AppTransition.TRANSIT_TASK_OPEN
3024                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3025    }
3026
3027    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3028            String processName, String abiOverride, int uid, Runnable crashHandler) {
3029        synchronized(this) {
3030            ApplicationInfo info = new ApplicationInfo();
3031            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3032            // For isolated processes, the former contains the parent's uid and the latter the
3033            // actual uid of the isolated process.
3034            // In the special case introduced by this method (which is, starting an isolated
3035            // process directly from the SystemServer without an actual parent app process) the
3036            // closest thing to a parent's uid is SYSTEM_UID.
3037            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3038            // the |isolated| logic in the ProcessRecord constructor.
3039            info.uid = Process.SYSTEM_UID;
3040            info.processName = processName;
3041            info.className = entryPoint;
3042            info.packageName = "android";
3043            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3044                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3045                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3046                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3047                    crashHandler);
3048            return proc != null ? proc.pid : 0;
3049        }
3050    }
3051
3052    final ProcessRecord startProcessLocked(String processName,
3053            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3054            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3055            boolean isolated, boolean keepIfLarge) {
3056        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3057                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3058                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3059                null /* crashHandler */);
3060    }
3061
3062    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3063            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3064            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3065            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3066        long startTime = SystemClock.elapsedRealtime();
3067        ProcessRecord app;
3068        if (!isolated) {
3069            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3070            checkTime(startTime, "startProcess: after getProcessRecord");
3071
3072            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3073                // If we are in the background, then check to see if this process
3074                // is bad.  If so, we will just silently fail.
3075                if (mBadProcesses.get(info.processName, info.uid) != null) {
3076                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3077                            + "/" + info.processName);
3078                    return null;
3079                }
3080            } else {
3081                // When the user is explicitly starting a process, then clear its
3082                // crash count so that we won't make it bad until they see at
3083                // least one crash dialog again, and make the process good again
3084                // if it had been bad.
3085                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3086                        + "/" + info.processName);
3087                mProcessCrashTimes.remove(info.processName, info.uid);
3088                if (mBadProcesses.get(info.processName, info.uid) != null) {
3089                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3090                            UserHandle.getUserId(info.uid), info.uid,
3091                            info.processName);
3092                    mBadProcesses.remove(info.processName, info.uid);
3093                    if (app != null) {
3094                        app.bad = false;
3095                    }
3096                }
3097            }
3098        } else {
3099            // If this is an isolated process, it can't re-use an existing process.
3100            app = null;
3101        }
3102
3103        // We don't have to do anything more if:
3104        // (1) There is an existing application record; and
3105        // (2) The caller doesn't think it is dead, OR there is no thread
3106        //     object attached to it so we know it couldn't have crashed; and
3107        // (3) There is a pid assigned to it, so it is either starting or
3108        //     already running.
3109        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3110                + " app=" + app + " knownToBeDead=" + knownToBeDead
3111                + " thread=" + (app != null ? app.thread : null)
3112                + " pid=" + (app != null ? app.pid : -1));
3113        if (app != null && app.pid > 0) {
3114            if (!knownToBeDead || app.thread == null) {
3115                // We already have the app running, or are waiting for it to
3116                // come up (we have a pid but not yet its thread), so keep it.
3117                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3118                // If this is a new package in the process, add the package to the list
3119                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3120                checkTime(startTime, "startProcess: done, added package to proc");
3121                return app;
3122            }
3123
3124            // An application record is attached to a previous process,
3125            // clean it up now.
3126            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3127            checkTime(startTime, "startProcess: bad proc running, killing");
3128            Process.killProcessGroup(app.info.uid, app.pid);
3129            handleAppDiedLocked(app, true, true);
3130            checkTime(startTime, "startProcess: done killing old proc");
3131        }
3132
3133        String hostingNameStr = hostingName != null
3134                ? hostingName.flattenToShortString() : null;
3135
3136        if (app == null) {
3137            checkTime(startTime, "startProcess: creating new process record");
3138            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3139            if (app == null) {
3140                Slog.w(TAG, "Failed making new process record for "
3141                        + processName + "/" + info.uid + " isolated=" + isolated);
3142                return null;
3143            }
3144            app.crashHandler = crashHandler;
3145            checkTime(startTime, "startProcess: done creating new process record");
3146        } else {
3147            // If this is a new package in the process, add the package to the list
3148            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3149            checkTime(startTime, "startProcess: added package to existing proc");
3150        }
3151
3152        // If the system is not ready yet, then hold off on starting this
3153        // process until it is.
3154        if (!mProcessesReady
3155                && !isAllowedWhileBooting(info)
3156                && !allowWhileBooting) {
3157            if (!mProcessesOnHold.contains(app)) {
3158                mProcessesOnHold.add(app);
3159            }
3160            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3161                    "System not ready, putting on hold: " + app);
3162            checkTime(startTime, "startProcess: returning with proc on hold");
3163            return app;
3164        }
3165
3166        checkTime(startTime, "startProcess: stepping in to startProcess");
3167        startProcessLocked(
3168                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3169        checkTime(startTime, "startProcess: done starting proc!");
3170        return (app.pid != 0) ? app : null;
3171    }
3172
3173    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3174        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3175    }
3176
3177    private final void startProcessLocked(ProcessRecord app,
3178            String hostingType, String hostingNameStr) {
3179        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3180                null /* entryPoint */, null /* entryPointArgs */);
3181    }
3182
3183    private final void startProcessLocked(ProcessRecord app, String hostingType,
3184            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3185        long startTime = SystemClock.elapsedRealtime();
3186        if (app.pid > 0 && app.pid != MY_PID) {
3187            checkTime(startTime, "startProcess: removing from pids map");
3188            synchronized (mPidsSelfLocked) {
3189                mPidsSelfLocked.remove(app.pid);
3190                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3191            }
3192            checkTime(startTime, "startProcess: done removing from pids map");
3193            app.setPid(0);
3194        }
3195
3196        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3197                "startProcessLocked removing on hold: " + app);
3198        mProcessesOnHold.remove(app);
3199
3200        checkTime(startTime, "startProcess: starting to update cpu stats");
3201        updateCpuStats();
3202        checkTime(startTime, "startProcess: done updating cpu stats");
3203
3204        try {
3205            try {
3206                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3207                    // This is caught below as if we had failed to fork zygote
3208                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3209                }
3210            } catch (RemoteException e) {
3211                throw e.rethrowAsRuntimeException();
3212            }
3213
3214            int uid = app.uid;
3215            int[] gids = null;
3216            int mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
3217            if (!app.isolated) {
3218                int[] permGids = null;
3219                try {
3220                    checkTime(startTime, "startProcess: getting gids from package manager");
3221                    permGids = AppGlobals.getPackageManager().getPackageGids(app.info.packageName,
3222                            app.userId);
3223                } catch (RemoteException e) {
3224                    throw e.rethrowAsRuntimeException();
3225                }
3226
3227                /*
3228                 * Add shared application and profile GIDs so applications can share some
3229                 * resources like shared libraries and access user-wide resources
3230                 */
3231                if (ArrayUtils.isEmpty(permGids)) {
3232                    gids = new int[2];
3233                } else {
3234                    gids = new int[permGids.length + 2];
3235                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3236                }
3237                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3238                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3239            }
3240            checkTime(startTime, "startProcess: building args");
3241            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3242                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3243                        && mTopComponent != null
3244                        && app.processName.equals(mTopComponent.getPackageName())) {
3245                    uid = 0;
3246                }
3247                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3248                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3249                    uid = 0;
3250                }
3251            }
3252            int debugFlags = 0;
3253            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3254                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3255                // Also turn on CheckJNI for debuggable apps. It's quite
3256                // awkward to turn on otherwise.
3257                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3258            }
3259            // Run the app in safe mode if its manifest requests so or the
3260            // system is booted in safe mode.
3261            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3262                mSafeMode == true) {
3263                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3264            }
3265            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3266                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3267            }
3268            String jitDebugProperty = SystemProperties.get("debug.usejit");
3269            if ("true".equals(jitDebugProperty)) {
3270                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3271            } else if (!"false".equals(jitDebugProperty)) {
3272                // If we didn't force disable by setting false, defer to the dalvik vm options.
3273                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3274                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3275                }
3276            }
3277            String genCFIDebugProperty = SystemProperties.get("debug.gencfi");
3278            if ("true".equals(genCFIDebugProperty)) {
3279                debugFlags |= Zygote.DEBUG_GENERATE_CFI;
3280            }
3281            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3282                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3283            }
3284            if ("1".equals(SystemProperties.get("debug.assert"))) {
3285                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3286            }
3287
3288            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3289            if (requiredAbi == null) {
3290                requiredAbi = Build.SUPPORTED_ABIS[0];
3291            }
3292
3293            String instructionSet = null;
3294            if (app.info.primaryCpuAbi != null) {
3295                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3296            }
3297
3298            app.gids = gids;
3299            app.requiredAbi = requiredAbi;
3300            app.instructionSet = instructionSet;
3301
3302            // Start the process.  It will either succeed and return a result containing
3303            // the PID of the new process, or else throw a RuntimeException.
3304            boolean isActivityProcess = (entryPoint == null);
3305            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3306            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3307                    app.processName);
3308            checkTime(startTime, "startProcess: asking zygote to start proc");
3309            Process.ProcessStartResult startResult = Process.start(entryPoint,
3310                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3311                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3312                    app.info.dataDir, entryPointArgs);
3313            checkTime(startTime, "startProcess: returned from zygote!");
3314            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3315
3316            if (app.isolated) {
3317                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3318            }
3319            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3320            checkTime(startTime, "startProcess: done updating battery stats");
3321
3322            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3323                    UserHandle.getUserId(uid), startResult.pid, uid,
3324                    app.processName, hostingType,
3325                    hostingNameStr != null ? hostingNameStr : "");
3326
3327            if (app.persistent) {
3328                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3329            }
3330
3331            checkTime(startTime, "startProcess: building log message");
3332            StringBuilder buf = mStringBuilder;
3333            buf.setLength(0);
3334            buf.append("Start proc ");
3335            buf.append(startResult.pid);
3336            buf.append(':');
3337            buf.append(app.processName);
3338            buf.append('/');
3339            UserHandle.formatUid(buf, uid);
3340            if (!isActivityProcess) {
3341                buf.append(" [");
3342                buf.append(entryPoint);
3343                buf.append("]");
3344            }
3345            buf.append(" for ");
3346            buf.append(hostingType);
3347            if (hostingNameStr != null) {
3348                buf.append(" ");
3349                buf.append(hostingNameStr);
3350            }
3351            Slog.i(TAG, buf.toString());
3352            app.setPid(startResult.pid);
3353            app.usingWrapper = startResult.usingWrapper;
3354            app.removed = false;
3355            app.killed = false;
3356            app.killedByAm = false;
3357            checkTime(startTime, "startProcess: starting to update pids map");
3358            synchronized (mPidsSelfLocked) {
3359                this.mPidsSelfLocked.put(startResult.pid, app);
3360                if (isActivityProcess) {
3361                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3362                    msg.obj = app;
3363                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3364                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3365                }
3366            }
3367            checkTime(startTime, "startProcess: done updating pids map");
3368        } catch (RuntimeException e) {
3369            // XXX do better error recovery.
3370            app.setPid(0);
3371            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3372            if (app.isolated) {
3373                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3374            }
3375            Slog.e(TAG, "Failure starting process " + app.processName, e);
3376        }
3377    }
3378
3379    void updateUsageStats(ActivityRecord component, boolean resumed) {
3380        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3381                "updateUsageStats: comp=" + component + "res=" + resumed);
3382        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3383        if (resumed) {
3384            if (mUsageStatsService != null) {
3385                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3386                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3387            }
3388            synchronized (stats) {
3389                stats.noteActivityResumedLocked(component.app.uid);
3390            }
3391        } else {
3392            if (mUsageStatsService != null) {
3393                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3394                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3395            }
3396            synchronized (stats) {
3397                stats.noteActivityPausedLocked(component.app.uid);
3398            }
3399        }
3400    }
3401
3402    Intent getHomeIntent() {
3403        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3404        intent.setComponent(mTopComponent);
3405        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3406            intent.addCategory(Intent.CATEGORY_HOME);
3407        }
3408        return intent;
3409    }
3410
3411    boolean startHomeActivityLocked(int userId, String reason) {
3412        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3413                && mTopAction == null) {
3414            // We are running in factory test mode, but unable to find
3415            // the factory test app, so just sit around displaying the
3416            // error message and don't try to start anything.
3417            return false;
3418        }
3419        Intent intent = getHomeIntent();
3420        ActivityInfo aInfo =
3421            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3422        if (aInfo != null) {
3423            intent.setComponent(new ComponentName(
3424                    aInfo.applicationInfo.packageName, aInfo.name));
3425            // Don't do this if the home app is currently being
3426            // instrumented.
3427            aInfo = new ActivityInfo(aInfo);
3428            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3429            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3430                    aInfo.applicationInfo.uid, true);
3431            if (app == null || app.instrumentationClass == null) {
3432                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3433                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3434            }
3435        }
3436
3437        return true;
3438    }
3439
3440    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3441        ActivityInfo ai = null;
3442        ComponentName comp = intent.getComponent();
3443        try {
3444            if (comp != null) {
3445                // Factory test.
3446                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3447            } else {
3448                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3449                        intent,
3450                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3451                        flags, userId);
3452
3453                if (info != null) {
3454                    ai = info.activityInfo;
3455                }
3456            }
3457        } catch (RemoteException e) {
3458            // ignore
3459        }
3460
3461        return ai;
3462    }
3463
3464    /**
3465     * Starts the "new version setup screen" if appropriate.
3466     */
3467    void startSetupActivityLocked() {
3468        // Only do this once per boot.
3469        if (mCheckedForSetup) {
3470            return;
3471        }
3472
3473        // We will show this screen if the current one is a different
3474        // version than the last one shown, and we are not running in
3475        // low-level factory test mode.
3476        final ContentResolver resolver = mContext.getContentResolver();
3477        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3478                Settings.Global.getInt(resolver,
3479                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3480            mCheckedForSetup = true;
3481
3482            // See if we should be showing the platform update setup UI.
3483            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3484            List<ResolveInfo> ris = mContext.getPackageManager()
3485                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3486
3487            // We don't allow third party apps to replace this.
3488            ResolveInfo ri = null;
3489            for (int i=0; ris != null && i<ris.size(); i++) {
3490                if ((ris.get(i).activityInfo.applicationInfo.flags
3491                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3492                    ri = ris.get(i);
3493                    break;
3494                }
3495            }
3496
3497            if (ri != null) {
3498                String vers = ri.activityInfo.metaData != null
3499                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3500                        : null;
3501                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3502                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3503                            Intent.METADATA_SETUP_VERSION);
3504                }
3505                String lastVers = Settings.Secure.getString(
3506                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3507                if (vers != null && !vers.equals(lastVers)) {
3508                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3509                    intent.setComponent(new ComponentName(
3510                            ri.activityInfo.packageName, ri.activityInfo.name));
3511                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3512                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3513                            null);
3514                }
3515            }
3516        }
3517    }
3518
3519    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3520        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3521    }
3522
3523    void enforceNotIsolatedCaller(String caller) {
3524        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3525            throw new SecurityException("Isolated process not allowed to call " + caller);
3526        }
3527    }
3528
3529    void enforceShellRestriction(String restriction, int userHandle) {
3530        if (Binder.getCallingUid() == Process.SHELL_UID) {
3531            if (userHandle < 0
3532                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3533                throw new SecurityException("Shell does not have permission to access user "
3534                        + userHandle);
3535            }
3536        }
3537    }
3538
3539    @Override
3540    public int getFrontActivityScreenCompatMode() {
3541        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3542        synchronized (this) {
3543            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3544        }
3545    }
3546
3547    @Override
3548    public void setFrontActivityScreenCompatMode(int mode) {
3549        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3550                "setFrontActivityScreenCompatMode");
3551        synchronized (this) {
3552            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3553        }
3554    }
3555
3556    @Override
3557    public int getPackageScreenCompatMode(String packageName) {
3558        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3559        synchronized (this) {
3560            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3561        }
3562    }
3563
3564    @Override
3565    public void setPackageScreenCompatMode(String packageName, int mode) {
3566        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3567                "setPackageScreenCompatMode");
3568        synchronized (this) {
3569            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3570        }
3571    }
3572
3573    @Override
3574    public boolean getPackageAskScreenCompat(String packageName) {
3575        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3576        synchronized (this) {
3577            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3578        }
3579    }
3580
3581    @Override
3582    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3583        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3584                "setPackageAskScreenCompat");
3585        synchronized (this) {
3586            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3587        }
3588    }
3589
3590    @Override
3591    public int getPackageProcessState(String packageName) {
3592        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3593        synchronized (this) {
3594            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3595                final ProcessRecord proc = mLruProcesses.get(i);
3596                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3597                        || procState > proc.setProcState) {
3598                    boolean found = false;
3599                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3600                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3601                            procState = proc.setProcState;
3602                            found = true;
3603                        }
3604                    }
3605                    if (proc.pkgDeps != null && !found) {
3606                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3607                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3608                                procState = proc.setProcState;
3609                                break;
3610                            }
3611                        }
3612                    }
3613                }
3614            }
3615        }
3616        return procState;
3617    }
3618
3619    @Override
3620    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3621        synchronized (this) {
3622            final ProcessRecord app = getProcessRecordLocked(process, userId, true);
3623            if (app == null) {
3624                return false;
3625            }
3626            if (app.trimMemoryLevel < level && app.thread != null &&
3627                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3628                            app.trimMemoryLevel >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)) {
3629                try {
3630                    app.thread.scheduleTrimMemory(level);
3631                    app.trimMemoryLevel = level;
3632                    return true;
3633                } catch (RemoteException e) {
3634                    // Fallthrough to failure case.
3635                }
3636            }
3637        }
3638        return false;
3639    }
3640
3641    private void dispatchProcessesChanged() {
3642        int N;
3643        synchronized (this) {
3644            N = mPendingProcessChanges.size();
3645            if (mActiveProcessChanges.length < N) {
3646                mActiveProcessChanges = new ProcessChangeItem[N];
3647            }
3648            mPendingProcessChanges.toArray(mActiveProcessChanges);
3649            mPendingProcessChanges.clear();
3650            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3651                    "*** Delivering " + N + " process changes");
3652        }
3653
3654        int i = mProcessObservers.beginBroadcast();
3655        while (i > 0) {
3656            i--;
3657            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3658            if (observer != null) {
3659                try {
3660                    for (int j=0; j<N; j++) {
3661                        ProcessChangeItem item = mActiveProcessChanges[j];
3662                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3663                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3664                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3665                                    + item.uid + ": " + item.foregroundActivities);
3666                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3667                                    item.foregroundActivities);
3668                        }
3669                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3670                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3671                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3672                                    + ": " + item.processState);
3673                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3674                        }
3675                    }
3676                } catch (RemoteException e) {
3677                }
3678            }
3679        }
3680        mProcessObservers.finishBroadcast();
3681
3682        synchronized (this) {
3683            for (int j=0; j<N; j++) {
3684                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3685            }
3686        }
3687    }
3688
3689    private void dispatchProcessDied(int pid, int uid) {
3690        int i = mProcessObservers.beginBroadcast();
3691        while (i > 0) {
3692            i--;
3693            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3694            if (observer != null) {
3695                try {
3696                    observer.onProcessDied(pid, uid);
3697                } catch (RemoteException e) {
3698                }
3699            }
3700        }
3701        mProcessObservers.finishBroadcast();
3702    }
3703
3704    private void dispatchUidsChanged() {
3705        int N;
3706        synchronized (this) {
3707            N = mPendingUidChanges.size();
3708            if (mActiveUidChanges.length < N) {
3709                mActiveUidChanges = new UidRecord.ChangeItem[N];
3710            }
3711            for (int i=0; i<N; i++) {
3712                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3713                mActiveUidChanges[i] = change;
3714                change.uidRecord.pendingChange = null;
3715                change.uidRecord = null;
3716            }
3717            mPendingUidChanges.clear();
3718            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3719                    "*** Delivering " + N + " uid changes");
3720        }
3721
3722        if (mLocalPowerManager != null) {
3723            for (int j=0; j<N; j++) {
3724                UidRecord.ChangeItem item = mActiveUidChanges[j];
3725                if (item.gone) {
3726                    mLocalPowerManager.uidGone(item.uid);
3727                } else {
3728                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3729                }
3730            }
3731        }
3732
3733        int i = mUidObservers.beginBroadcast();
3734        while (i > 0) {
3735            i--;
3736            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3737            if (observer != null) {
3738                try {
3739                    for (int j=0; j<N; j++) {
3740                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3741                        if (item.gone) {
3742                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3743                                    "UID gone uid=" + item.uid);
3744                            observer.onUidGone(item.uid);
3745                        } else {
3746                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3747                                    "UID CHANGED uid=" + item.uid
3748                                    + ": " + item.processState);
3749                            observer.onUidStateChanged(item.uid, item.processState);
3750                        }
3751                    }
3752                } catch (RemoteException e) {
3753                }
3754            }
3755        }
3756        mUidObservers.finishBroadcast();
3757
3758        synchronized (this) {
3759            for (int j=0; j<N; j++) {
3760                mAvailUidChanges.add(mActiveUidChanges[j]);
3761            }
3762        }
3763    }
3764
3765    @Override
3766    public final int startActivity(IApplicationThread caller, String callingPackage,
3767            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3768            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3769        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3770            resultWho, requestCode, startFlags, profilerInfo, options,
3771            UserHandle.getCallingUserId());
3772    }
3773
3774    @Override
3775    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3776            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3777            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3778        enforceNotIsolatedCaller("startActivity");
3779        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3780                false, ALLOW_FULL_ONLY, "startActivity", null);
3781        // TODO: Switch to user app stacks here.
3782        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3783                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3784                profilerInfo, null, null, options, userId, null, null);
3785    }
3786
3787    @Override
3788    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3789            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3790            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3791
3792        // This is very dangerous -- it allows you to perform a start activity (including
3793        // permission grants) as any app that may launch one of your own activities.  So
3794        // we will only allow this to be done from activities that are part of the core framework,
3795        // and then only when they are running as the system.
3796        final ActivityRecord sourceRecord;
3797        final int targetUid;
3798        final String targetPackage;
3799        synchronized (this) {
3800            if (resultTo == null) {
3801                throw new SecurityException("Must be called from an activity");
3802            }
3803            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3804            if (sourceRecord == null) {
3805                throw new SecurityException("Called with bad activity token: " + resultTo);
3806            }
3807            if (!sourceRecord.info.packageName.equals("android")) {
3808                throw new SecurityException(
3809                        "Must be called from an activity that is declared in the android package");
3810            }
3811            if (sourceRecord.app == null) {
3812                throw new SecurityException("Called without a process attached to activity");
3813            }
3814            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3815                // This is still okay, as long as this activity is running under the
3816                // uid of the original calling activity.
3817                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3818                    throw new SecurityException(
3819                            "Calling activity in uid " + sourceRecord.app.uid
3820                                    + " must be system uid or original calling uid "
3821                                    + sourceRecord.launchedFromUid);
3822                }
3823            }
3824            targetUid = sourceRecord.launchedFromUid;
3825            targetPackage = sourceRecord.launchedFromPackage;
3826        }
3827
3828        if (userId == UserHandle.USER_NULL) {
3829            userId = UserHandle.getUserId(sourceRecord.app.uid);
3830        }
3831
3832        // TODO: Switch to user app stacks here.
3833        try {
3834            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3835                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3836                    null, null, options, userId, null, null);
3837            return ret;
3838        } catch (SecurityException e) {
3839            // XXX need to figure out how to propagate to original app.
3840            // A SecurityException here is generally actually a fault of the original
3841            // calling activity (such as a fairly granting permissions), so propagate it
3842            // back to them.
3843            /*
3844            StringBuilder msg = new StringBuilder();
3845            msg.append("While launching");
3846            msg.append(intent.toString());
3847            msg.append(": ");
3848            msg.append(e.getMessage());
3849            */
3850            throw e;
3851        }
3852    }
3853
3854    @Override
3855    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3856            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3857            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3858        enforceNotIsolatedCaller("startActivityAndWait");
3859        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3860                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3861        WaitResult res = new WaitResult();
3862        // TODO: Switch to user app stacks here.
3863        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3864                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3865                options, userId, null, null);
3866        return res;
3867    }
3868
3869    @Override
3870    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3871            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3872            int startFlags, Configuration config, Bundle options, int userId) {
3873        enforceNotIsolatedCaller("startActivityWithConfig");
3874        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3875                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3876        // TODO: Switch to user app stacks here.
3877        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3878                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3879                null, null, config, options, userId, null, null);
3880        return ret;
3881    }
3882
3883    @Override
3884    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3885            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3886            int requestCode, int flagsMask, int flagsValues, Bundle options)
3887            throws TransactionTooLargeException {
3888        enforceNotIsolatedCaller("startActivityIntentSender");
3889        // Refuse possible leaked file descriptors
3890        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3891            throw new IllegalArgumentException("File descriptors passed in Intent");
3892        }
3893
3894        IIntentSender sender = intent.getTarget();
3895        if (!(sender instanceof PendingIntentRecord)) {
3896            throw new IllegalArgumentException("Bad PendingIntent object");
3897        }
3898
3899        PendingIntentRecord pir = (PendingIntentRecord)sender;
3900
3901        synchronized (this) {
3902            // If this is coming from the currently resumed activity, it is
3903            // effectively saying that app switches are allowed at this point.
3904            final ActivityStack stack = getFocusedStack();
3905            if (stack.mResumedActivity != null &&
3906                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3907                mAppSwitchesAllowedTime = 0;
3908            }
3909        }
3910        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3911                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3912        return ret;
3913    }
3914
3915    @Override
3916    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3917            Intent intent, String resolvedType, IVoiceInteractionSession session,
3918            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3919            Bundle options, int userId) {
3920        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3921                != PackageManager.PERMISSION_GRANTED) {
3922            String msg = "Permission Denial: startVoiceActivity() from pid="
3923                    + Binder.getCallingPid()
3924                    + ", uid=" + Binder.getCallingUid()
3925                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3926            Slog.w(TAG, msg);
3927            throw new SecurityException(msg);
3928        }
3929        if (session == null || interactor == null) {
3930            throw new NullPointerException("null session or interactor");
3931        }
3932        userId = handleIncomingUser(callingPid, callingUid, userId,
3933                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3934        // TODO: Switch to user app stacks here.
3935        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3936                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3937                null, options, userId, null, null);
3938    }
3939
3940    @Override
3941    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3942        synchronized (this) {
3943            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3944                if (keepAwake) {
3945                    mVoiceWakeLock.acquire();
3946                } else {
3947                    mVoiceWakeLock.release();
3948                }
3949            }
3950        }
3951    }
3952
3953    @Override
3954    public boolean startNextMatchingActivity(IBinder callingActivity,
3955            Intent intent, Bundle options) {
3956        // Refuse possible leaked file descriptors
3957        if (intent != null && intent.hasFileDescriptors() == true) {
3958            throw new IllegalArgumentException("File descriptors passed in Intent");
3959        }
3960
3961        synchronized (this) {
3962            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3963            if (r == null) {
3964                ActivityOptions.abort(options);
3965                return false;
3966            }
3967            if (r.app == null || r.app.thread == null) {
3968                // The caller is not running...  d'oh!
3969                ActivityOptions.abort(options);
3970                return false;
3971            }
3972            intent = new Intent(intent);
3973            // The caller is not allowed to change the data.
3974            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3975            // And we are resetting to find the next component...
3976            intent.setComponent(null);
3977
3978            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3979
3980            ActivityInfo aInfo = null;
3981            try {
3982                List<ResolveInfo> resolves =
3983                    AppGlobals.getPackageManager().queryIntentActivities(
3984                            intent, r.resolvedType,
3985                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3986                            UserHandle.getCallingUserId());
3987
3988                // Look for the original activity in the list...
3989                final int N = resolves != null ? resolves.size() : 0;
3990                for (int i=0; i<N; i++) {
3991                    ResolveInfo rInfo = resolves.get(i);
3992                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3993                            && rInfo.activityInfo.name.equals(r.info.name)) {
3994                        // We found the current one...  the next matching is
3995                        // after it.
3996                        i++;
3997                        if (i<N) {
3998                            aInfo = resolves.get(i).activityInfo;
3999                        }
4000                        if (debug) {
4001                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4002                                    + "/" + r.info.name);
4003                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4004                                    + "/" + aInfo.name);
4005                        }
4006                        break;
4007                    }
4008                }
4009            } catch (RemoteException e) {
4010            }
4011
4012            if (aInfo == null) {
4013                // Nobody who is next!
4014                ActivityOptions.abort(options);
4015                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4016                return false;
4017            }
4018
4019            intent.setComponent(new ComponentName(
4020                    aInfo.applicationInfo.packageName, aInfo.name));
4021            intent.setFlags(intent.getFlags()&~(
4022                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4023                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4024                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4025                    Intent.FLAG_ACTIVITY_NEW_TASK));
4026
4027            // Okay now we need to start the new activity, replacing the
4028            // currently running activity.  This is a little tricky because
4029            // we want to start the new one as if the current one is finished,
4030            // but not finish the current one first so that there is no flicker.
4031            // And thus...
4032            final boolean wasFinishing = r.finishing;
4033            r.finishing = true;
4034
4035            // Propagate reply information over to the new activity.
4036            final ActivityRecord resultTo = r.resultTo;
4037            final String resultWho = r.resultWho;
4038            final int requestCode = r.requestCode;
4039            r.resultTo = null;
4040            if (resultTo != null) {
4041                resultTo.removeResultsLocked(r, resultWho, requestCode);
4042            }
4043
4044            final long origId = Binder.clearCallingIdentity();
4045            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4046                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4047                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4048                    -1, r.launchedFromUid, 0, options, false, null, null, null);
4049            Binder.restoreCallingIdentity(origId);
4050
4051            r.finishing = wasFinishing;
4052            if (res != ActivityManager.START_SUCCESS) {
4053                return false;
4054            }
4055            return true;
4056        }
4057    }
4058
4059    @Override
4060    public final int startActivityFromRecents(int taskId, Bundle options) {
4061        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4062            String msg = "Permission Denial: startActivityFromRecents called without " +
4063                    START_TASKS_FROM_RECENTS;
4064            Slog.w(TAG, msg);
4065            throw new SecurityException(msg);
4066        }
4067        return startActivityFromRecentsInner(taskId, options);
4068    }
4069
4070    final int startActivityFromRecentsInner(int taskId, Bundle options) {
4071        final TaskRecord task;
4072        final int callingUid;
4073        final String callingPackage;
4074        final Intent intent;
4075        final int userId;
4076        synchronized (this) {
4077            task = mRecentTasks.taskForIdLocked(taskId);
4078            if (task == null) {
4079                throw new IllegalArgumentException("Task " + taskId + " not found.");
4080            }
4081            if (task.getRootActivity() != null) {
4082                moveTaskToFrontLocked(task.taskId, 0, null);
4083                return ActivityManager.START_TASK_TO_FRONT;
4084            }
4085            callingUid = task.mCallingUid;
4086            callingPackage = task.mCallingPackage;
4087            intent = task.intent;
4088            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4089            userId = task.userId;
4090        }
4091        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4092                options, userId, null, task);
4093    }
4094
4095    final int startActivityInPackage(int uid, String callingPackage,
4096            Intent intent, String resolvedType, IBinder resultTo,
4097            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4098            IActivityContainer container, TaskRecord inTask) {
4099
4100        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4101                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4102
4103        // TODO: Switch to user app stacks here.
4104        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4105                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4106                null, null, null, options, userId, container, inTask);
4107        return ret;
4108    }
4109
4110    @Override
4111    public final int startActivities(IApplicationThread caller, String callingPackage,
4112            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4113            int userId) {
4114        enforceNotIsolatedCaller("startActivities");
4115        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4116                false, ALLOW_FULL_ONLY, "startActivity", null);
4117        // TODO: Switch to user app stacks here.
4118        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4119                resolvedTypes, resultTo, options, userId);
4120        return ret;
4121    }
4122
4123    final int startActivitiesInPackage(int uid, String callingPackage,
4124            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4125            Bundle options, int userId) {
4126
4127        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4128                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4129        // TODO: Switch to user app stacks here.
4130        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4131                resultTo, options, userId);
4132        return ret;
4133    }
4134
4135    @Override
4136    public void reportActivityFullyDrawn(IBinder token) {
4137        synchronized (this) {
4138            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4139            if (r == null) {
4140                return;
4141            }
4142            r.reportFullyDrawnLocked();
4143        }
4144    }
4145
4146    @Override
4147    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4148        synchronized (this) {
4149            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4150            if (r == null) {
4151                return;
4152            }
4153            if (r.task != null && r.task.mResizeable) {
4154                // Fixed screen orientation isn't supported with resizeable activities.
4155                return;
4156            }
4157            final long origId = Binder.clearCallingIdentity();
4158            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4159            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4160                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4161            if (config != null) {
4162                r.frozenBeforeDestroy = true;
4163                if (!updateConfigurationLocked(config, r, false, false)) {
4164                    mStackSupervisor.resumeTopActivitiesLocked();
4165                }
4166            }
4167            Binder.restoreCallingIdentity(origId);
4168        }
4169    }
4170
4171    @Override
4172    public int getRequestedOrientation(IBinder token) {
4173        synchronized (this) {
4174            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4175            if (r == null) {
4176                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4177            }
4178            return mWindowManager.getAppOrientation(r.appToken);
4179        }
4180    }
4181
4182    /**
4183     * This is the internal entry point for handling Activity.finish().
4184     *
4185     * @param token The Binder token referencing the Activity we want to finish.
4186     * @param resultCode Result code, if any, from this Activity.
4187     * @param resultData Result data (Intent), if any, from this Activity.
4188     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4189     *            the root Activity in the task.
4190     *
4191     * @return Returns true if the activity successfully finished, or false if it is still running.
4192     */
4193    @Override
4194    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4195            boolean finishTask) {
4196        // Refuse possible leaked file descriptors
4197        if (resultData != null && resultData.hasFileDescriptors() == true) {
4198            throw new IllegalArgumentException("File descriptors passed in Intent");
4199        }
4200
4201        synchronized(this) {
4202            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4203            if (r == null) {
4204                return true;
4205            }
4206            // Keep track of the root activity of the task before we finish it
4207            TaskRecord tr = r.task;
4208            ActivityRecord rootR = tr.getRootActivity();
4209            if (rootR == null) {
4210                Slog.w(TAG, "Finishing task with all activities already finished");
4211            }
4212            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4213            // finish.
4214            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4215                    mStackSupervisor.isLastLockedTask(tr)) {
4216                Slog.i(TAG, "Not finishing task in lock task mode");
4217                mStackSupervisor.showLockTaskToast();
4218                return false;
4219            }
4220            if (mController != null) {
4221                // Find the first activity that is not finishing.
4222                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4223                if (next != null) {
4224                    // ask watcher if this is allowed
4225                    boolean resumeOK = true;
4226                    try {
4227                        resumeOK = mController.activityResuming(next.packageName);
4228                    } catch (RemoteException e) {
4229                        mController = null;
4230                        Watchdog.getInstance().setActivityController(null);
4231                    }
4232
4233                    if (!resumeOK) {
4234                        Slog.i(TAG, "Not finishing activity because controller resumed");
4235                        return false;
4236                    }
4237                }
4238            }
4239            final long origId = Binder.clearCallingIdentity();
4240            try {
4241                boolean res;
4242                if (finishTask && r == rootR) {
4243                    // If requested, remove the task that is associated to this activity only if it
4244                    // was the root activity in the task. The result code and data is ignored
4245                    // because we don't support returning them across task boundaries.
4246                    res = removeTaskByIdLocked(tr.taskId, false);
4247                    if (!res) {
4248                        Slog.i(TAG, "Removing task failed to finish activity");
4249                    }
4250                } else {
4251                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4252                            resultData, "app-request", true);
4253                    if (!res) {
4254                        Slog.i(TAG, "Failed to finish by app-request");
4255                    }
4256                }
4257                return res;
4258            } finally {
4259                Binder.restoreCallingIdentity(origId);
4260            }
4261        }
4262    }
4263
4264    @Override
4265    public final void finishHeavyWeightApp() {
4266        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4267                != PackageManager.PERMISSION_GRANTED) {
4268            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4269                    + Binder.getCallingPid()
4270                    + ", uid=" + Binder.getCallingUid()
4271                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4272            Slog.w(TAG, msg);
4273            throw new SecurityException(msg);
4274        }
4275
4276        synchronized(this) {
4277            if (mHeavyWeightProcess == null) {
4278                return;
4279            }
4280
4281            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4282            for (int i = 0; i < activities.size(); i++) {
4283                ActivityRecord r = activities.get(i);
4284                if (!r.finishing && r.isInStackLocked()) {
4285                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4286                            null, "finish-heavy", true);
4287                }
4288            }
4289
4290            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4291                    mHeavyWeightProcess.userId, 0));
4292            mHeavyWeightProcess = null;
4293        }
4294    }
4295
4296    @Override
4297    public void crashApplication(int uid, int initialPid, String packageName,
4298            String message) {
4299        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4300                != PackageManager.PERMISSION_GRANTED) {
4301            String msg = "Permission Denial: crashApplication() from pid="
4302                    + Binder.getCallingPid()
4303                    + ", uid=" + Binder.getCallingUid()
4304                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4305            Slog.w(TAG, msg);
4306            throw new SecurityException(msg);
4307        }
4308
4309        synchronized(this) {
4310            ProcessRecord proc = null;
4311
4312            // Figure out which process to kill.  We don't trust that initialPid
4313            // still has any relation to current pids, so must scan through the
4314            // list.
4315            synchronized (mPidsSelfLocked) {
4316                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4317                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4318                    if (p.uid != uid) {
4319                        continue;
4320                    }
4321                    if (p.pid == initialPid) {
4322                        proc = p;
4323                        break;
4324                    }
4325                    if (p.pkgList.containsKey(packageName)) {
4326                        proc = p;
4327                    }
4328                }
4329            }
4330
4331            if (proc == null) {
4332                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4333                        + " initialPid=" + initialPid
4334                        + " packageName=" + packageName);
4335                return;
4336            }
4337
4338            if (proc.thread != null) {
4339                if (proc.pid == Process.myPid()) {
4340                    Log.w(TAG, "crashApplication: trying to crash self!");
4341                    return;
4342                }
4343                long ident = Binder.clearCallingIdentity();
4344                try {
4345                    proc.thread.scheduleCrash(message);
4346                } catch (RemoteException e) {
4347                }
4348                Binder.restoreCallingIdentity(ident);
4349            }
4350        }
4351    }
4352
4353    @Override
4354    public final void finishSubActivity(IBinder token, String resultWho,
4355            int requestCode) {
4356        synchronized(this) {
4357            final long origId = Binder.clearCallingIdentity();
4358            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4359            if (r != null) {
4360                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4361            }
4362            Binder.restoreCallingIdentity(origId);
4363        }
4364    }
4365
4366    @Override
4367    public boolean finishActivityAffinity(IBinder token) {
4368        synchronized(this) {
4369            final long origId = Binder.clearCallingIdentity();
4370            try {
4371                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4372                if (r == null) {
4373                    return false;
4374                }
4375
4376                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4377                // can finish.
4378                final TaskRecord task = r.task;
4379                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4380                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4381                    mStackSupervisor.showLockTaskToast();
4382                    return false;
4383                }
4384                return task.stack.finishActivityAffinityLocked(r);
4385            } finally {
4386                Binder.restoreCallingIdentity(origId);
4387            }
4388        }
4389    }
4390
4391    @Override
4392    public void finishVoiceTask(IVoiceInteractionSession session) {
4393        synchronized(this) {
4394            final long origId = Binder.clearCallingIdentity();
4395            try {
4396                mStackSupervisor.finishVoiceTask(session);
4397            } finally {
4398                Binder.restoreCallingIdentity(origId);
4399            }
4400        }
4401
4402    }
4403
4404    @Override
4405    public boolean releaseActivityInstance(IBinder token) {
4406        synchronized(this) {
4407            final long origId = Binder.clearCallingIdentity();
4408            try {
4409                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4410                if (r == null) {
4411                    return false;
4412                }
4413                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4414            } finally {
4415                Binder.restoreCallingIdentity(origId);
4416            }
4417        }
4418    }
4419
4420    @Override
4421    public void releaseSomeActivities(IApplicationThread appInt) {
4422        synchronized(this) {
4423            final long origId = Binder.clearCallingIdentity();
4424            try {
4425                ProcessRecord app = getRecordForAppLocked(appInt);
4426                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4427            } finally {
4428                Binder.restoreCallingIdentity(origId);
4429            }
4430        }
4431    }
4432
4433    @Override
4434    public boolean willActivityBeVisible(IBinder token) {
4435        synchronized(this) {
4436            ActivityStack stack = ActivityRecord.getStackLocked(token);
4437            if (stack != null) {
4438                return stack.willActivityBeVisibleLocked(token);
4439            }
4440            return false;
4441        }
4442    }
4443
4444    @Override
4445    public void overridePendingTransition(IBinder token, String packageName,
4446            int enterAnim, int exitAnim) {
4447        synchronized(this) {
4448            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4449            if (self == null) {
4450                return;
4451            }
4452
4453            final long origId = Binder.clearCallingIdentity();
4454
4455            if (self.state == ActivityState.RESUMED
4456                    || self.state == ActivityState.PAUSING) {
4457                mWindowManager.overridePendingAppTransition(packageName,
4458                        enterAnim, exitAnim, null);
4459            }
4460
4461            Binder.restoreCallingIdentity(origId);
4462        }
4463    }
4464
4465    /**
4466     * Main function for removing an existing process from the activity manager
4467     * as a result of that process going away.  Clears out all connections
4468     * to the process.
4469     */
4470    private final void handleAppDiedLocked(ProcessRecord app,
4471            boolean restarting, boolean allowRestart) {
4472        int pid = app.pid;
4473        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4474        if (!kept && !restarting) {
4475            removeLruProcessLocked(app);
4476            if (pid > 0) {
4477                ProcessList.remove(pid);
4478            }
4479        }
4480
4481        if (mProfileProc == app) {
4482            clearProfilerLocked();
4483        }
4484
4485        // Remove this application's activities from active lists.
4486        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4487
4488        app.activities.clear();
4489
4490        if (app.instrumentationClass != null) {
4491            Slog.w(TAG, "Crash of app " + app.processName
4492                  + " running instrumentation " + app.instrumentationClass);
4493            Bundle info = new Bundle();
4494            info.putString("shortMsg", "Process crashed.");
4495            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4496        }
4497
4498        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4499            // If there was nothing to resume, and we are not already
4500            // restarting this process, but there is a visible activity that
4501            // is hosted by the process...  then make sure all visible
4502            // activities are running, taking care of restarting this
4503            // process.
4504            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4505        }
4506    }
4507
4508    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4509        IBinder threadBinder = thread.asBinder();
4510        // Find the application record.
4511        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4512            ProcessRecord rec = mLruProcesses.get(i);
4513            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4514                return i;
4515            }
4516        }
4517        return -1;
4518    }
4519
4520    final ProcessRecord getRecordForAppLocked(
4521            IApplicationThread thread) {
4522        if (thread == null) {
4523            return null;
4524        }
4525
4526        int appIndex = getLRURecordIndexForAppLocked(thread);
4527        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4528    }
4529
4530    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4531        // If there are no longer any background processes running,
4532        // and the app that died was not running instrumentation,
4533        // then tell everyone we are now low on memory.
4534        boolean haveBg = false;
4535        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4536            ProcessRecord rec = mLruProcesses.get(i);
4537            if (rec.thread != null
4538                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4539                haveBg = true;
4540                break;
4541            }
4542        }
4543
4544        if (!haveBg) {
4545            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4546            if (doReport) {
4547                long now = SystemClock.uptimeMillis();
4548                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4549                    doReport = false;
4550                } else {
4551                    mLastMemUsageReportTime = now;
4552                }
4553            }
4554            final ArrayList<ProcessMemInfo> memInfos
4555                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4556            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4557            long now = SystemClock.uptimeMillis();
4558            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4559                ProcessRecord rec = mLruProcesses.get(i);
4560                if (rec == dyingProc || rec.thread == null) {
4561                    continue;
4562                }
4563                if (doReport) {
4564                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4565                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4566                }
4567                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4568                    // The low memory report is overriding any current
4569                    // state for a GC request.  Make sure to do
4570                    // heavy/important/visible/foreground processes first.
4571                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4572                        rec.lastRequestedGc = 0;
4573                    } else {
4574                        rec.lastRequestedGc = rec.lastLowMemory;
4575                    }
4576                    rec.reportLowMemory = true;
4577                    rec.lastLowMemory = now;
4578                    mProcessesToGc.remove(rec);
4579                    addProcessToGcListLocked(rec);
4580                }
4581            }
4582            if (doReport) {
4583                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4584                mHandler.sendMessage(msg);
4585            }
4586            scheduleAppGcsLocked();
4587        }
4588    }
4589
4590    final void appDiedLocked(ProcessRecord app) {
4591       appDiedLocked(app, app.pid, app.thread, false);
4592    }
4593
4594    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4595            boolean fromBinderDied) {
4596        // First check if this ProcessRecord is actually active for the pid.
4597        synchronized (mPidsSelfLocked) {
4598            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4599            if (curProc != app) {
4600                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4601                return;
4602            }
4603        }
4604
4605        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4606        synchronized (stats) {
4607            stats.noteProcessDiedLocked(app.info.uid, pid);
4608        }
4609
4610        if (!app.killed) {
4611            if (!fromBinderDied) {
4612                Process.killProcessQuiet(pid);
4613            }
4614            Process.killProcessGroup(app.info.uid, pid);
4615            app.killed = true;
4616        }
4617
4618        // Clean up already done if the process has been re-started.
4619        if (app.pid == pid && app.thread != null &&
4620                app.thread.asBinder() == thread.asBinder()) {
4621            boolean doLowMem = app.instrumentationClass == null;
4622            boolean doOomAdj = doLowMem;
4623            if (!app.killedByAm) {
4624                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4625                        + ") has died");
4626                mAllowLowerMemLevel = true;
4627            } else {
4628                // Note that we always want to do oom adj to update our state with the
4629                // new number of procs.
4630                mAllowLowerMemLevel = false;
4631                doLowMem = false;
4632            }
4633            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4634            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4635                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4636            handleAppDiedLocked(app, false, true);
4637
4638            if (doOomAdj) {
4639                updateOomAdjLocked();
4640            }
4641            if (doLowMem) {
4642                doLowMemReportIfNeededLocked(app);
4643            }
4644        } else if (app.pid != pid) {
4645            // A new process has already been started.
4646            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4647                    + ") has died and restarted (pid " + app.pid + ").");
4648            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4649        } else if (DEBUG_PROCESSES) {
4650            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4651                    + thread.asBinder());
4652        }
4653    }
4654
4655    /**
4656     * If a stack trace dump file is configured, dump process stack traces.
4657     * @param clearTraces causes the dump file to be erased prior to the new
4658     *    traces being written, if true; when false, the new traces will be
4659     *    appended to any existing file content.
4660     * @param firstPids of dalvik VM processes to dump stack traces for first
4661     * @param lastPids of dalvik VM processes to dump stack traces for last
4662     * @param nativeProcs optional list of native process names to dump stack crawls
4663     * @return file containing stack traces, or null if no dump file is configured
4664     */
4665    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4666            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4667        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4668        if (tracesPath == null || tracesPath.length() == 0) {
4669            return null;
4670        }
4671
4672        File tracesFile = new File(tracesPath);
4673        try {
4674            File tracesDir = tracesFile.getParentFile();
4675            if (!tracesDir.exists()) {
4676                tracesDir.mkdirs();
4677                if (!SELinux.restorecon(tracesDir)) {
4678                    return null;
4679                }
4680            }
4681            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4682
4683            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4684            tracesFile.createNewFile();
4685            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4686        } catch (IOException e) {
4687            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4688            return null;
4689        }
4690
4691        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4692        return tracesFile;
4693    }
4694
4695    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4696            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4697        // Use a FileObserver to detect when traces finish writing.
4698        // The order of traces is considered important to maintain for legibility.
4699        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4700            @Override
4701            public synchronized void onEvent(int event, String path) { notify(); }
4702        };
4703
4704        try {
4705            observer.startWatching();
4706
4707            // First collect all of the stacks of the most important pids.
4708            if (firstPids != null) {
4709                try {
4710                    int num = firstPids.size();
4711                    for (int i = 0; i < num; i++) {
4712                        synchronized (observer) {
4713                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4714                            observer.wait(200);  // Wait for write-close, give up after 200msec
4715                        }
4716                    }
4717                } catch (InterruptedException e) {
4718                    Slog.wtf(TAG, e);
4719                }
4720            }
4721
4722            // Next collect the stacks of the native pids
4723            if (nativeProcs != null) {
4724                int[] pids = Process.getPidsForCommands(nativeProcs);
4725                if (pids != null) {
4726                    for (int pid : pids) {
4727                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4728                    }
4729                }
4730            }
4731
4732            // Lastly, measure CPU usage.
4733            if (processCpuTracker != null) {
4734                processCpuTracker.init();
4735                System.gc();
4736                processCpuTracker.update();
4737                try {
4738                    synchronized (processCpuTracker) {
4739                        processCpuTracker.wait(500); // measure over 1/2 second.
4740                    }
4741                } catch (InterruptedException e) {
4742                }
4743                processCpuTracker.update();
4744
4745                // We'll take the stack crawls of just the top apps using CPU.
4746                final int N = processCpuTracker.countWorkingStats();
4747                int numProcs = 0;
4748                for (int i=0; i<N && numProcs<5; i++) {
4749                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4750                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4751                        numProcs++;
4752                        try {
4753                            synchronized (observer) {
4754                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4755                                observer.wait(200);  // Wait for write-close, give up after 200msec
4756                            }
4757                        } catch (InterruptedException e) {
4758                            Slog.wtf(TAG, e);
4759                        }
4760
4761                    }
4762                }
4763            }
4764        } finally {
4765            observer.stopWatching();
4766        }
4767    }
4768
4769    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4770        if (true || IS_USER_BUILD) {
4771            return;
4772        }
4773        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4774        if (tracesPath == null || tracesPath.length() == 0) {
4775            return;
4776        }
4777
4778        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4779        StrictMode.allowThreadDiskWrites();
4780        try {
4781            final File tracesFile = new File(tracesPath);
4782            final File tracesDir = tracesFile.getParentFile();
4783            final File tracesTmp = new File(tracesDir, "__tmp__");
4784            try {
4785                if (!tracesDir.exists()) {
4786                    tracesDir.mkdirs();
4787                    if (!SELinux.restorecon(tracesDir.getPath())) {
4788                        return;
4789                    }
4790                }
4791                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4792
4793                if (tracesFile.exists()) {
4794                    tracesTmp.delete();
4795                    tracesFile.renameTo(tracesTmp);
4796                }
4797                StringBuilder sb = new StringBuilder();
4798                Time tobj = new Time();
4799                tobj.set(System.currentTimeMillis());
4800                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4801                sb.append(": ");
4802                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4803                sb.append(" since ");
4804                sb.append(msg);
4805                FileOutputStream fos = new FileOutputStream(tracesFile);
4806                fos.write(sb.toString().getBytes());
4807                if (app == null) {
4808                    fos.write("\n*** No application process!".getBytes());
4809                }
4810                fos.close();
4811                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4812            } catch (IOException e) {
4813                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4814                return;
4815            }
4816
4817            if (app != null) {
4818                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4819                firstPids.add(app.pid);
4820                dumpStackTraces(tracesPath, firstPids, null, null, null);
4821            }
4822
4823            File lastTracesFile = null;
4824            File curTracesFile = null;
4825            for (int i=9; i>=0; i--) {
4826                String name = String.format(Locale.US, "slow%02d.txt", i);
4827                curTracesFile = new File(tracesDir, name);
4828                if (curTracesFile.exists()) {
4829                    if (lastTracesFile != null) {
4830                        curTracesFile.renameTo(lastTracesFile);
4831                    } else {
4832                        curTracesFile.delete();
4833                    }
4834                }
4835                lastTracesFile = curTracesFile;
4836            }
4837            tracesFile.renameTo(curTracesFile);
4838            if (tracesTmp.exists()) {
4839                tracesTmp.renameTo(tracesFile);
4840            }
4841        } finally {
4842            StrictMode.setThreadPolicy(oldPolicy);
4843        }
4844    }
4845
4846    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4847            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4848        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4849        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4850
4851        if (mController != null) {
4852            try {
4853                // 0 == continue, -1 = kill process immediately
4854                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4855                if (res < 0 && app.pid != MY_PID) {
4856                    app.kill("anr", true);
4857                }
4858            } catch (RemoteException e) {
4859                mController = null;
4860                Watchdog.getInstance().setActivityController(null);
4861            }
4862        }
4863
4864        long anrTime = SystemClock.uptimeMillis();
4865        if (MONITOR_CPU_USAGE) {
4866            updateCpuStatsNow();
4867        }
4868
4869        synchronized (this) {
4870            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4871            if (mShuttingDown) {
4872                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4873                return;
4874            } else if (app.notResponding) {
4875                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4876                return;
4877            } else if (app.crashing) {
4878                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4879                return;
4880            }
4881
4882            // In case we come through here for the same app before completing
4883            // this one, mark as anring now so we will bail out.
4884            app.notResponding = true;
4885
4886            // Log the ANR to the event log.
4887            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4888                    app.processName, app.info.flags, annotation);
4889
4890            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4891            firstPids.add(app.pid);
4892
4893            int parentPid = app.pid;
4894            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4895            if (parentPid != app.pid) firstPids.add(parentPid);
4896
4897            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4898
4899            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4900                ProcessRecord r = mLruProcesses.get(i);
4901                if (r != null && r.thread != null) {
4902                    int pid = r.pid;
4903                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4904                        if (r.persistent) {
4905                            firstPids.add(pid);
4906                        } else {
4907                            lastPids.put(pid, Boolean.TRUE);
4908                        }
4909                    }
4910                }
4911            }
4912        }
4913
4914        // Log the ANR to the main log.
4915        StringBuilder info = new StringBuilder();
4916        info.setLength(0);
4917        info.append("ANR in ").append(app.processName);
4918        if (activity != null && activity.shortComponentName != null) {
4919            info.append(" (").append(activity.shortComponentName).append(")");
4920        }
4921        info.append("\n");
4922        info.append("PID: ").append(app.pid).append("\n");
4923        if (annotation != null) {
4924            info.append("Reason: ").append(annotation).append("\n");
4925        }
4926        if (parent != null && parent != activity) {
4927            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4928        }
4929
4930        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4931
4932        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4933                NATIVE_STACKS_OF_INTEREST);
4934
4935        String cpuInfo = null;
4936        if (MONITOR_CPU_USAGE) {
4937            updateCpuStatsNow();
4938            synchronized (mProcessCpuTracker) {
4939                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4940            }
4941            info.append(processCpuTracker.printCurrentLoad());
4942            info.append(cpuInfo);
4943        }
4944
4945        info.append(processCpuTracker.printCurrentState(anrTime));
4946
4947        Slog.e(TAG, info.toString());
4948        if (tracesFile == null) {
4949            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4950            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4951        }
4952
4953        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4954                cpuInfo, tracesFile, null);
4955
4956        if (mController != null) {
4957            try {
4958                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4959                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4960                if (res != 0) {
4961                    if (res < 0 && app.pid != MY_PID) {
4962                        app.kill("anr", true);
4963                    } else {
4964                        synchronized (this) {
4965                            mServices.scheduleServiceTimeoutLocked(app);
4966                        }
4967                    }
4968                    return;
4969                }
4970            } catch (RemoteException e) {
4971                mController = null;
4972                Watchdog.getInstance().setActivityController(null);
4973            }
4974        }
4975
4976        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4977        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4978                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4979
4980        synchronized (this) {
4981            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
4982
4983            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4984                app.kill("bg anr", true);
4985                return;
4986            }
4987
4988            // Set the app's notResponding state, and look up the errorReportReceiver
4989            makeAppNotRespondingLocked(app,
4990                    activity != null ? activity.shortComponentName : null,
4991                    annotation != null ? "ANR " + annotation : "ANR",
4992                    info.toString());
4993
4994            // Bring up the infamous App Not Responding dialog
4995            Message msg = Message.obtain();
4996            HashMap<String, Object> map = new HashMap<String, Object>();
4997            msg.what = SHOW_NOT_RESPONDING_MSG;
4998            msg.obj = map;
4999            msg.arg1 = aboveSystem ? 1 : 0;
5000            map.put("app", app);
5001            if (activity != null) {
5002                map.put("activity", activity);
5003            }
5004
5005            mUiHandler.sendMessage(msg);
5006        }
5007    }
5008
5009    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5010        if (!mLaunchWarningShown) {
5011            mLaunchWarningShown = true;
5012            mUiHandler.post(new Runnable() {
5013                @Override
5014                public void run() {
5015                    synchronized (ActivityManagerService.this) {
5016                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5017                        d.show();
5018                        mUiHandler.postDelayed(new Runnable() {
5019                            @Override
5020                            public void run() {
5021                                synchronized (ActivityManagerService.this) {
5022                                    d.dismiss();
5023                                    mLaunchWarningShown = false;
5024                                }
5025                            }
5026                        }, 4000);
5027                    }
5028                }
5029            });
5030        }
5031    }
5032
5033    @Override
5034    public boolean clearApplicationUserData(final String packageName,
5035            final IPackageDataObserver observer, int userId) {
5036        enforceNotIsolatedCaller("clearApplicationUserData");
5037        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5038            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5039        }
5040        int uid = Binder.getCallingUid();
5041        int pid = Binder.getCallingPid();
5042        userId = handleIncomingUser(pid, uid,
5043                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5044        long callingId = Binder.clearCallingIdentity();
5045        try {
5046            IPackageManager pm = AppGlobals.getPackageManager();
5047            int pkgUid = -1;
5048            synchronized(this) {
5049                try {
5050                    pkgUid = pm.getPackageUid(packageName, userId);
5051                } catch (RemoteException e) {
5052                }
5053                if (pkgUid == -1) {
5054                    Slog.w(TAG, "Invalid packageName: " + packageName);
5055                    if (observer != null) {
5056                        try {
5057                            observer.onRemoveCompleted(packageName, false);
5058                        } catch (RemoteException e) {
5059                            Slog.i(TAG, "Observer no longer exists.");
5060                        }
5061                    }
5062                    return false;
5063                }
5064                if (uid == pkgUid || checkComponentPermission(
5065                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5066                        pid, uid, -1, true)
5067                        == PackageManager.PERMISSION_GRANTED) {
5068                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5069                } else {
5070                    throw new SecurityException("PID " + pid + " does not have permission "
5071                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5072                                    + " of package " + packageName);
5073                }
5074
5075                // Remove all tasks match the cleared application package and user
5076                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5077                    final TaskRecord tr = mRecentTasks.get(i);
5078                    final String taskPackageName =
5079                            tr.getBaseIntent().getComponent().getPackageName();
5080                    if (tr.userId != userId) continue;
5081                    if (!taskPackageName.equals(packageName)) continue;
5082                    removeTaskByIdLocked(tr.taskId, false);
5083                }
5084            }
5085
5086            try {
5087                // Clear application user data
5088                pm.clearApplicationUserData(packageName, observer, userId);
5089
5090                synchronized(this) {
5091                    // Remove all permissions granted from/to this package
5092                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5093                }
5094
5095                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5096                        Uri.fromParts("package", packageName, null));
5097                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5098                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5099                        null, null, 0, null, null, null, null, false, false, userId);
5100            } catch (RemoteException e) {
5101            }
5102        } finally {
5103            Binder.restoreCallingIdentity(callingId);
5104        }
5105        return true;
5106    }
5107
5108    @Override
5109    public void killBackgroundProcesses(final String packageName, int userId) {
5110        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5111                != PackageManager.PERMISSION_GRANTED &&
5112                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5113                        != PackageManager.PERMISSION_GRANTED) {
5114            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5115                    + Binder.getCallingPid()
5116                    + ", uid=" + Binder.getCallingUid()
5117                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5118            Slog.w(TAG, msg);
5119            throw new SecurityException(msg);
5120        }
5121
5122        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5123                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5124        long callingId = Binder.clearCallingIdentity();
5125        try {
5126            IPackageManager pm = AppGlobals.getPackageManager();
5127            synchronized(this) {
5128                int appId = -1;
5129                try {
5130                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5131                } catch (RemoteException e) {
5132                }
5133                if (appId == -1) {
5134                    Slog.w(TAG, "Invalid packageName: " + packageName);
5135                    return;
5136                }
5137                killPackageProcessesLocked(packageName, appId, userId,
5138                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5139            }
5140        } finally {
5141            Binder.restoreCallingIdentity(callingId);
5142        }
5143    }
5144
5145    @Override
5146    public void killAllBackgroundProcesses() {
5147        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5148                != PackageManager.PERMISSION_GRANTED) {
5149            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5150                    + Binder.getCallingPid()
5151                    + ", uid=" + Binder.getCallingUid()
5152                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5153            Slog.w(TAG, msg);
5154            throw new SecurityException(msg);
5155        }
5156
5157        long callingId = Binder.clearCallingIdentity();
5158        try {
5159            synchronized(this) {
5160                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5161                final int NP = mProcessNames.getMap().size();
5162                for (int ip=0; ip<NP; ip++) {
5163                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5164                    final int NA = apps.size();
5165                    for (int ia=0; ia<NA; ia++) {
5166                        ProcessRecord app = apps.valueAt(ia);
5167                        if (app.persistent) {
5168                            // we don't kill persistent processes
5169                            continue;
5170                        }
5171                        if (app.removed) {
5172                            procs.add(app);
5173                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5174                            app.removed = true;
5175                            procs.add(app);
5176                        }
5177                    }
5178                }
5179
5180                int N = procs.size();
5181                for (int i=0; i<N; i++) {
5182                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5183                }
5184                mAllowLowerMemLevel = true;
5185                updateOomAdjLocked();
5186                doLowMemReportIfNeededLocked(null);
5187            }
5188        } finally {
5189            Binder.restoreCallingIdentity(callingId);
5190        }
5191    }
5192
5193    @Override
5194    public void forceStopPackage(final String packageName, int userId) {
5195        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5196                != PackageManager.PERMISSION_GRANTED) {
5197            String msg = "Permission Denial: forceStopPackage() from pid="
5198                    + Binder.getCallingPid()
5199                    + ", uid=" + Binder.getCallingUid()
5200                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5201            Slog.w(TAG, msg);
5202            throw new SecurityException(msg);
5203        }
5204        final int callingPid = Binder.getCallingPid();
5205        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5206                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5207        long callingId = Binder.clearCallingIdentity();
5208        try {
5209            IPackageManager pm = AppGlobals.getPackageManager();
5210            synchronized(this) {
5211                int[] users = userId == UserHandle.USER_ALL
5212                        ? getUsersLocked() : new int[] { userId };
5213                for (int user : users) {
5214                    int pkgUid = -1;
5215                    try {
5216                        pkgUid = pm.getPackageUid(packageName, user);
5217                    } catch (RemoteException e) {
5218                    }
5219                    if (pkgUid == -1) {
5220                        Slog.w(TAG, "Invalid packageName: " + packageName);
5221                        continue;
5222                    }
5223                    try {
5224                        pm.setPackageStoppedState(packageName, true, user);
5225                    } catch (RemoteException e) {
5226                    } catch (IllegalArgumentException e) {
5227                        Slog.w(TAG, "Failed trying to unstop package "
5228                                + packageName + ": " + e);
5229                    }
5230                    if (isUserRunningLocked(user, false)) {
5231                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5232                    }
5233                }
5234            }
5235        } finally {
5236            Binder.restoreCallingIdentity(callingId);
5237        }
5238    }
5239
5240    @Override
5241    public void addPackageDependency(String packageName) {
5242        synchronized (this) {
5243            int callingPid = Binder.getCallingPid();
5244            if (callingPid == Process.myPid()) {
5245                //  Yeah, um, no.
5246                return;
5247            }
5248            ProcessRecord proc;
5249            synchronized (mPidsSelfLocked) {
5250                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5251            }
5252            if (proc != null) {
5253                if (proc.pkgDeps == null) {
5254                    proc.pkgDeps = new ArraySet<String>(1);
5255                }
5256                proc.pkgDeps.add(packageName);
5257            }
5258        }
5259    }
5260
5261    /*
5262     * The pkg name and app id have to be specified.
5263     */
5264    @Override
5265    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5266        if (pkg == null) {
5267            return;
5268        }
5269        // Make sure the uid is valid.
5270        if (appid < 0) {
5271            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5272            return;
5273        }
5274        int callerUid = Binder.getCallingUid();
5275        // Only the system server can kill an application
5276        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5277            // Post an aysnc message to kill the application
5278            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5279            msg.arg1 = appid;
5280            msg.arg2 = 0;
5281            Bundle bundle = new Bundle();
5282            bundle.putString("pkg", pkg);
5283            bundle.putString("reason", reason);
5284            msg.obj = bundle;
5285            mHandler.sendMessage(msg);
5286        } else {
5287            throw new SecurityException(callerUid + " cannot kill pkg: " +
5288                    pkg);
5289        }
5290    }
5291
5292    @Override
5293    public void closeSystemDialogs(String reason) {
5294        enforceNotIsolatedCaller("closeSystemDialogs");
5295
5296        final int pid = Binder.getCallingPid();
5297        final int uid = Binder.getCallingUid();
5298        final long origId = Binder.clearCallingIdentity();
5299        try {
5300            synchronized (this) {
5301                // Only allow this from foreground processes, so that background
5302                // applications can't abuse it to prevent system UI from being shown.
5303                if (uid >= Process.FIRST_APPLICATION_UID) {
5304                    ProcessRecord proc;
5305                    synchronized (mPidsSelfLocked) {
5306                        proc = mPidsSelfLocked.get(pid);
5307                    }
5308                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5309                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5310                                + " from background process " + proc);
5311                        return;
5312                    }
5313                }
5314                closeSystemDialogsLocked(reason);
5315            }
5316        } finally {
5317            Binder.restoreCallingIdentity(origId);
5318        }
5319    }
5320
5321    void closeSystemDialogsLocked(String reason) {
5322        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5323        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5324                | Intent.FLAG_RECEIVER_FOREGROUND);
5325        if (reason != null) {
5326            intent.putExtra("reason", reason);
5327        }
5328        mWindowManager.closeSystemDialogs(reason);
5329
5330        mStackSupervisor.closeSystemDialogsLocked();
5331
5332        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5333                AppOpsManager.OP_NONE, null, false, false,
5334                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5335    }
5336
5337    @Override
5338    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5339        enforceNotIsolatedCaller("getProcessMemoryInfo");
5340        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5341        for (int i=pids.length-1; i>=0; i--) {
5342            ProcessRecord proc;
5343            int oomAdj;
5344            synchronized (this) {
5345                synchronized (mPidsSelfLocked) {
5346                    proc = mPidsSelfLocked.get(pids[i]);
5347                    oomAdj = proc != null ? proc.setAdj : 0;
5348                }
5349            }
5350            infos[i] = new Debug.MemoryInfo();
5351            Debug.getMemoryInfo(pids[i], infos[i]);
5352            if (proc != null) {
5353                synchronized (this) {
5354                    if (proc.thread != null && proc.setAdj == oomAdj) {
5355                        // Record this for posterity if the process has been stable.
5356                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5357                                infos[i].getTotalUss(), false, proc.pkgList);
5358                    }
5359                }
5360            }
5361        }
5362        return infos;
5363    }
5364
5365    @Override
5366    public long[] getProcessPss(int[] pids) {
5367        enforceNotIsolatedCaller("getProcessPss");
5368        long[] pss = new long[pids.length];
5369        for (int i=pids.length-1; i>=0; i--) {
5370            ProcessRecord proc;
5371            int oomAdj;
5372            synchronized (this) {
5373                synchronized (mPidsSelfLocked) {
5374                    proc = mPidsSelfLocked.get(pids[i]);
5375                    oomAdj = proc != null ? proc.setAdj : 0;
5376                }
5377            }
5378            long[] tmpUss = new long[1];
5379            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5380            if (proc != null) {
5381                synchronized (this) {
5382                    if (proc.thread != null && proc.setAdj == oomAdj) {
5383                        // Record this for posterity if the process has been stable.
5384                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5385                    }
5386                }
5387            }
5388        }
5389        return pss;
5390    }
5391
5392    @Override
5393    public void killApplicationProcess(String processName, int uid) {
5394        if (processName == null) {
5395            return;
5396        }
5397
5398        int callerUid = Binder.getCallingUid();
5399        // Only the system server can kill an application
5400        if (callerUid == Process.SYSTEM_UID) {
5401            synchronized (this) {
5402                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5403                if (app != null && app.thread != null) {
5404                    try {
5405                        app.thread.scheduleSuicide();
5406                    } catch (RemoteException e) {
5407                        // If the other end already died, then our work here is done.
5408                    }
5409                } else {
5410                    Slog.w(TAG, "Process/uid not found attempting kill of "
5411                            + processName + " / " + uid);
5412                }
5413            }
5414        } else {
5415            throw new SecurityException(callerUid + " cannot kill app process: " +
5416                    processName);
5417        }
5418    }
5419
5420    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5421        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5422                false, true, false, false, UserHandle.getUserId(uid), reason);
5423        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5424                Uri.fromParts("package", packageName, null));
5425        if (!mProcessesReady) {
5426            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5427                    | Intent.FLAG_RECEIVER_FOREGROUND);
5428        }
5429        intent.putExtra(Intent.EXTRA_UID, uid);
5430        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5431        broadcastIntentLocked(null, null, intent,
5432                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5433                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5434    }
5435
5436    private void forceStopUserLocked(int userId, String reason) {
5437        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5438        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5439        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5440                | Intent.FLAG_RECEIVER_FOREGROUND);
5441        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5442        broadcastIntentLocked(null, null, intent,
5443                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5444                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5445    }
5446
5447    private final boolean killPackageProcessesLocked(String packageName, int appId,
5448            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5449            boolean doit, boolean evenPersistent, String reason) {
5450        ArrayList<ProcessRecord> procs = new ArrayList<>();
5451
5452        // Remove all processes this package may have touched: all with the
5453        // same UID (except for the system or root user), and all whose name
5454        // matches the package name.
5455        final int NP = mProcessNames.getMap().size();
5456        for (int ip=0; ip<NP; ip++) {
5457            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5458            final int NA = apps.size();
5459            for (int ia=0; ia<NA; ia++) {
5460                ProcessRecord app = apps.valueAt(ia);
5461                if (app.persistent && !evenPersistent) {
5462                    // we don't kill persistent processes
5463                    continue;
5464                }
5465                if (app.removed) {
5466                    if (doit) {
5467                        procs.add(app);
5468                    }
5469                    continue;
5470                }
5471
5472                // Skip process if it doesn't meet our oom adj requirement.
5473                if (app.setAdj < minOomAdj) {
5474                    continue;
5475                }
5476
5477                // If no package is specified, we call all processes under the
5478                // give user id.
5479                if (packageName == null) {
5480                    if (app.userId != userId) {
5481                        continue;
5482                    }
5483                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5484                        continue;
5485                    }
5486                // Package has been specified, we want to hit all processes
5487                // that match it.  We need to qualify this by the processes
5488                // that are running under the specified app and user ID.
5489                } else {
5490                    final boolean isDep = app.pkgDeps != null
5491                            && app.pkgDeps.contains(packageName);
5492                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5493                        continue;
5494                    }
5495                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5496                        continue;
5497                    }
5498                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5499                        continue;
5500                    }
5501                }
5502
5503                // Process has passed all conditions, kill it!
5504                if (!doit) {
5505                    return true;
5506                }
5507                app.removed = true;
5508                procs.add(app);
5509            }
5510        }
5511
5512        int N = procs.size();
5513        for (int i=0; i<N; i++) {
5514            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5515        }
5516        updateOomAdjLocked();
5517        return N > 0;
5518    }
5519
5520    private void cleanupDisabledPackageComponentsLocked(
5521            String packageName, int userId, String[] changedClasses) {
5522
5523        Set<String> disabledClasses = null;
5524        boolean packageDisabled = false;
5525        IPackageManager pm = AppGlobals.getPackageManager();
5526
5527        if (changedClasses == null) {
5528            // Nothing changed...
5529            return;
5530        }
5531
5532        // Determine enable/disable state of the package and its components.
5533        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5534        for (int i = changedClasses.length - 1; i >= 0; i--) {
5535            final String changedClass = changedClasses[i];
5536
5537            if (changedClass.equals(packageName)) {
5538                try {
5539                    // Entire package setting changed
5540                    enabled = pm.getApplicationEnabledSetting(packageName,
5541                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5542                } catch (Exception e) {
5543                    // No such package/component; probably racing with uninstall.  In any
5544                    // event it means we have nothing further to do here.
5545                    return;
5546                }
5547                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5548                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5549                if (packageDisabled) {
5550                    // Entire package is disabled.
5551                    // No need to continue to check component states.
5552                    disabledClasses = null;
5553                    break;
5554                }
5555            } else {
5556                try {
5557                    enabled = pm.getComponentEnabledSetting(
5558                            new ComponentName(packageName, changedClass),
5559                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5560                } catch (Exception e) {
5561                    // As above, probably racing with uninstall.
5562                    return;
5563                }
5564                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5565                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5566                    if (disabledClasses == null) {
5567                        disabledClasses = new ArraySet<>(changedClasses.length);
5568                    }
5569                    disabledClasses.add(changedClass);
5570                }
5571            }
5572        }
5573
5574        if (!packageDisabled && disabledClasses == null) {
5575            // Nothing to do here...
5576            return;
5577        }
5578
5579        // Clean-up disabled activities.
5580        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5581                packageName, disabledClasses, true, false, userId) && mBooted) {
5582            mStackSupervisor.resumeTopActivitiesLocked();
5583            mStackSupervisor.scheduleIdleLocked();
5584        }
5585
5586        // Clean-up disabled tasks
5587        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5588
5589        // Clean-up disabled services.
5590        mServices.bringDownDisabledPackageServicesLocked(
5591                packageName, disabledClasses, userId, false, true);
5592
5593        // Clean-up disabled providers.
5594        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5595        mProviderMap.collectPackageProvidersLocked(
5596                packageName, disabledClasses, true, false, userId, providers);
5597        for (int i = providers.size() - 1; i >= 0; i--) {
5598            removeDyingProviderLocked(null, providers.get(i), true);
5599        }
5600
5601        // Clean-up disabled broadcast receivers.
5602        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5603            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5604                    packageName, disabledClasses, userId, true);
5605        }
5606
5607    }
5608
5609    private final boolean forceStopPackageLocked(String packageName, int appId,
5610            boolean callerWillRestart, boolean purgeCache, boolean doit,
5611            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5612        int i;
5613
5614        if (userId == UserHandle.USER_ALL && packageName == null) {
5615            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5616        }
5617
5618        if (appId < 0 && packageName != null) {
5619            try {
5620                appId = UserHandle.getAppId(
5621                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5622            } catch (RemoteException e) {
5623            }
5624        }
5625
5626        if (doit) {
5627            if (packageName != null) {
5628                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5629                        + " user=" + userId + ": " + reason);
5630            } else {
5631                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5632            }
5633
5634            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5635            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5636                SparseArray<Long> ba = pmap.valueAt(ip);
5637                for (i = ba.size() - 1; i >= 0; i--) {
5638                    boolean remove = false;
5639                    final int entUid = ba.keyAt(i);
5640                    if (packageName != null) {
5641                        if (userId == UserHandle.USER_ALL) {
5642                            if (UserHandle.getAppId(entUid) == appId) {
5643                                remove = true;
5644                            }
5645                        } else {
5646                            if (entUid == UserHandle.getUid(userId, appId)) {
5647                                remove = true;
5648                            }
5649                        }
5650                    } else if (UserHandle.getUserId(entUid) == userId) {
5651                        remove = true;
5652                    }
5653                    if (remove) {
5654                        ba.removeAt(i);
5655                    }
5656                }
5657                if (ba.size() == 0) {
5658                    pmap.removeAt(ip);
5659                }
5660            }
5661        }
5662
5663        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5664                -100, callerWillRestart, true, doit, evenPersistent,
5665                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5666
5667        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5668                packageName, null, doit, evenPersistent, userId)) {
5669            if (!doit) {
5670                return true;
5671            }
5672            didSomething = true;
5673        }
5674
5675        if (mServices.bringDownDisabledPackageServicesLocked(
5676                packageName, null, userId, evenPersistent, doit)) {
5677            if (!doit) {
5678                return true;
5679            }
5680            didSomething = true;
5681        }
5682
5683        if (packageName == null) {
5684            // Remove all sticky broadcasts from this user.
5685            mStickyBroadcasts.remove(userId);
5686        }
5687
5688        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5689        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5690                userId, providers)) {
5691            if (!doit) {
5692                return true;
5693            }
5694            didSomething = true;
5695        }
5696        for (i = providers.size() - 1; i >= 0; i--) {
5697            removeDyingProviderLocked(null, providers.get(i), true);
5698        }
5699
5700        // Remove transient permissions granted from/to this package/user
5701        removeUriPermissionsForPackageLocked(packageName, userId, false);
5702
5703        if (doit) {
5704            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5705                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5706                        packageName, null, userId, doit);
5707            }
5708        }
5709
5710        if (packageName == null || uninstalling) {
5711            // Remove pending intents.  For now we only do this when force
5712            // stopping users, because we have some problems when doing this
5713            // for packages -- app widgets are not currently cleaned up for
5714            // such packages, so they can be left with bad pending intents.
5715            if (mIntentSenderRecords.size() > 0) {
5716                Iterator<WeakReference<PendingIntentRecord>> it
5717                        = mIntentSenderRecords.values().iterator();
5718                while (it.hasNext()) {
5719                    WeakReference<PendingIntentRecord> wpir = it.next();
5720                    if (wpir == null) {
5721                        it.remove();
5722                        continue;
5723                    }
5724                    PendingIntentRecord pir = wpir.get();
5725                    if (pir == null) {
5726                        it.remove();
5727                        continue;
5728                    }
5729                    if (packageName == null) {
5730                        // Stopping user, remove all objects for the user.
5731                        if (pir.key.userId != userId) {
5732                            // Not the same user, skip it.
5733                            continue;
5734                        }
5735                    } else {
5736                        if (UserHandle.getAppId(pir.uid) != appId) {
5737                            // Different app id, skip it.
5738                            continue;
5739                        }
5740                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5741                            // Different user, skip it.
5742                            continue;
5743                        }
5744                        if (!pir.key.packageName.equals(packageName)) {
5745                            // Different package, skip it.
5746                            continue;
5747                        }
5748                    }
5749                    if (!doit) {
5750                        return true;
5751                    }
5752                    didSomething = true;
5753                    it.remove();
5754                    pir.canceled = true;
5755                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5756                        pir.key.activity.pendingResults.remove(pir.ref);
5757                    }
5758                }
5759            }
5760        }
5761
5762        if (doit) {
5763            if (purgeCache && packageName != null) {
5764                AttributeCache ac = AttributeCache.instance();
5765                if (ac != null) {
5766                    ac.removePackage(packageName);
5767                }
5768            }
5769            if (mBooted) {
5770                mStackSupervisor.resumeTopActivitiesLocked();
5771                mStackSupervisor.scheduleIdleLocked();
5772            }
5773        }
5774
5775        return didSomething;
5776    }
5777
5778    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5779        ProcessRecord old = mProcessNames.remove(name, uid);
5780        if (old != null) {
5781            old.uidRecord.numProcs--;
5782            if (old.uidRecord.numProcs == 0) {
5783                // No more processes using this uid, tell clients it is gone.
5784                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5785                        "No more processes in " + old.uidRecord);
5786                enqueueUidChangeLocked(old.uidRecord, true);
5787                mActiveUids.remove(uid);
5788            }
5789            old.uidRecord = null;
5790        }
5791        mIsolatedProcesses.remove(uid);
5792        return old;
5793    }
5794
5795    private final void addProcessNameLocked(ProcessRecord proc) {
5796        // We shouldn't already have a process under this name, but just in case we
5797        // need to clean up whatever may be there now.
5798        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5799        if (old != null) {
5800            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5801        }
5802        UidRecord uidRec = mActiveUids.get(proc.uid);
5803        if (uidRec == null) {
5804            uidRec = new UidRecord(proc.uid);
5805            // This is the first appearance of the uid, report it now!
5806            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5807                    "Creating new process uid: " + uidRec);
5808            mActiveUids.put(proc.uid, uidRec);
5809            enqueueUidChangeLocked(uidRec, false);
5810        }
5811        proc.uidRecord = uidRec;
5812        uidRec.numProcs++;
5813        mProcessNames.put(proc.processName, proc.uid, proc);
5814        if (proc.isolated) {
5815            mIsolatedProcesses.put(proc.uid, proc);
5816        }
5817    }
5818
5819    private final boolean removeProcessLocked(ProcessRecord app,
5820            boolean callerWillRestart, boolean allowRestart, String reason) {
5821        final String name = app.processName;
5822        final int uid = app.uid;
5823        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5824            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5825
5826        removeProcessNameLocked(name, uid);
5827        if (mHeavyWeightProcess == app) {
5828            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5829                    mHeavyWeightProcess.userId, 0));
5830            mHeavyWeightProcess = null;
5831        }
5832        boolean needRestart = false;
5833        if (app.pid > 0 && app.pid != MY_PID) {
5834            int pid = app.pid;
5835            synchronized (mPidsSelfLocked) {
5836                mPidsSelfLocked.remove(pid);
5837                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5838            }
5839            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5840            if (app.isolated) {
5841                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5842            }
5843            boolean willRestart = false;
5844            if (app.persistent && !app.isolated) {
5845                if (!callerWillRestart) {
5846                    willRestart = true;
5847                } else {
5848                    needRestart = true;
5849                }
5850            }
5851            app.kill(reason, true);
5852            handleAppDiedLocked(app, willRestart, allowRestart);
5853            if (willRestart) {
5854                removeLruProcessLocked(app);
5855                addAppLocked(app.info, false, null /* ABI override */);
5856            }
5857        } else {
5858            mRemovedProcesses.add(app);
5859        }
5860
5861        return needRestart;
5862    }
5863
5864    private final void processStartTimedOutLocked(ProcessRecord app) {
5865        final int pid = app.pid;
5866        boolean gone = false;
5867        synchronized (mPidsSelfLocked) {
5868            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5869            if (knownApp != null && knownApp.thread == null) {
5870                mPidsSelfLocked.remove(pid);
5871                gone = true;
5872            }
5873        }
5874
5875        if (gone) {
5876            Slog.w(TAG, "Process " + app + " failed to attach");
5877            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5878                    pid, app.uid, app.processName);
5879            removeProcessNameLocked(app.processName, app.uid);
5880            if (mHeavyWeightProcess == app) {
5881                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5882                        mHeavyWeightProcess.userId, 0));
5883                mHeavyWeightProcess = null;
5884            }
5885            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5886            if (app.isolated) {
5887                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5888            }
5889            // Take care of any launching providers waiting for this process.
5890            checkAppInLaunchingProvidersLocked(app, true);
5891            // Take care of any services that are waiting for the process.
5892            mServices.processStartTimedOutLocked(app);
5893            app.kill("start timeout", true);
5894            removeLruProcessLocked(app);
5895            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5896                Slog.w(TAG, "Unattached app died before backup, skipping");
5897                try {
5898                    IBackupManager bm = IBackupManager.Stub.asInterface(
5899                            ServiceManager.getService(Context.BACKUP_SERVICE));
5900                    bm.agentDisconnected(app.info.packageName);
5901                } catch (RemoteException e) {
5902                    // Can't happen; the backup manager is local
5903                }
5904            }
5905            if (isPendingBroadcastProcessLocked(pid)) {
5906                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5907                skipPendingBroadcastLocked(pid);
5908            }
5909        } else {
5910            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5911        }
5912    }
5913
5914    private final boolean attachApplicationLocked(IApplicationThread thread,
5915            int pid) {
5916
5917        // Find the application record that is being attached...  either via
5918        // the pid if we are running in multiple processes, or just pull the
5919        // next app record if we are emulating process with anonymous threads.
5920        ProcessRecord app;
5921        if (pid != MY_PID && pid >= 0) {
5922            synchronized (mPidsSelfLocked) {
5923                app = mPidsSelfLocked.get(pid);
5924            }
5925        } else {
5926            app = null;
5927        }
5928
5929        if (app == null) {
5930            Slog.w(TAG, "No pending application record for pid " + pid
5931                    + " (IApplicationThread " + thread + "); dropping process");
5932            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5933            if (pid > 0 && pid != MY_PID) {
5934                Process.killProcessQuiet(pid);
5935                //TODO: Process.killProcessGroup(app.info.uid, pid);
5936            } else {
5937                try {
5938                    thread.scheduleExit();
5939                } catch (Exception e) {
5940                    // Ignore exceptions.
5941                }
5942            }
5943            return false;
5944        }
5945
5946        // If this application record is still attached to a previous
5947        // process, clean it up now.
5948        if (app.thread != null) {
5949            handleAppDiedLocked(app, true, true);
5950        }
5951
5952        // Tell the process all about itself.
5953
5954        if (DEBUG_ALL) Slog.v(
5955                TAG, "Binding process pid " + pid + " to record " + app);
5956
5957        final String processName = app.processName;
5958        try {
5959            AppDeathRecipient adr = new AppDeathRecipient(
5960                    app, pid, thread);
5961            thread.asBinder().linkToDeath(adr, 0);
5962            app.deathRecipient = adr;
5963        } catch (RemoteException e) {
5964            app.resetPackageList(mProcessStats);
5965            startProcessLocked(app, "link fail", processName);
5966            return false;
5967        }
5968
5969        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5970
5971        app.makeActive(thread, mProcessStats);
5972        app.curAdj = app.setAdj = -100;
5973        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5974        app.forcingToForeground = null;
5975        updateProcessForegroundLocked(app, false, false);
5976        app.hasShownUi = false;
5977        app.debugging = false;
5978        app.cached = false;
5979        app.killedByAm = false;
5980
5981        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5982
5983        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5984        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5985
5986        if (!normalMode) {
5987            Slog.i(TAG, "Launching preboot mode app: " + app);
5988        }
5989
5990        if (DEBUG_ALL) Slog.v(
5991            TAG, "New app record " + app
5992            + " thread=" + thread.asBinder() + " pid=" + pid);
5993        try {
5994            int testMode = IApplicationThread.DEBUG_OFF;
5995            if (mDebugApp != null && mDebugApp.equals(processName)) {
5996                testMode = mWaitForDebugger
5997                    ? IApplicationThread.DEBUG_WAIT
5998                    : IApplicationThread.DEBUG_ON;
5999                app.debugging = true;
6000                if (mDebugTransient) {
6001                    mDebugApp = mOrigDebugApp;
6002                    mWaitForDebugger = mOrigWaitForDebugger;
6003                }
6004            }
6005            String profileFile = app.instrumentationProfileFile;
6006            ParcelFileDescriptor profileFd = null;
6007            int samplingInterval = 0;
6008            boolean profileAutoStop = false;
6009            if (mProfileApp != null && mProfileApp.equals(processName)) {
6010                mProfileProc = app;
6011                profileFile = mProfileFile;
6012                profileFd = mProfileFd;
6013                samplingInterval = mSamplingInterval;
6014                profileAutoStop = mAutoStopProfiler;
6015            }
6016            boolean enableOpenGlTrace = false;
6017            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6018                enableOpenGlTrace = true;
6019                mOpenGlTraceApp = null;
6020            }
6021
6022            // If the app is being launched for restore or full backup, set it up specially
6023            boolean isRestrictedBackupMode = false;
6024            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6025                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6026                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6027                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6028            }
6029
6030            ensurePackageDexOpt(app.instrumentationInfo != null
6031                    ? app.instrumentationInfo.packageName
6032                    : app.info.packageName);
6033            if (app.instrumentationClass != null) {
6034                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6035            }
6036            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6037                    + processName + " with config " + mConfiguration);
6038            ApplicationInfo appInfo = app.instrumentationInfo != null
6039                    ? app.instrumentationInfo : app.info;
6040            app.compat = compatibilityInfoForPackageLocked(appInfo);
6041            if (profileFd != null) {
6042                profileFd = profileFd.dup();
6043            }
6044            ProfilerInfo profilerInfo = profileFile == null ? null
6045                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6046            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6047                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6048                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6049                    isRestrictedBackupMode || !normalMode, app.persistent,
6050                    new Configuration(mConfiguration), app.compat,
6051                    getCommonServicesLocked(app.isolated),
6052                    mCoreSettingsObserver.getCoreSettingsLocked());
6053            updateLruProcessLocked(app, false, null);
6054            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6055        } catch (Exception e) {
6056            // todo: Yikes!  What should we do?  For now we will try to
6057            // start another process, but that could easily get us in
6058            // an infinite loop of restarting processes...
6059            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6060
6061            app.resetPackageList(mProcessStats);
6062            app.unlinkDeathRecipient();
6063            startProcessLocked(app, "bind fail", processName);
6064            return false;
6065        }
6066
6067        // Remove this record from the list of starting applications.
6068        mPersistentStartingProcesses.remove(app);
6069        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6070                "Attach application locked removing on hold: " + app);
6071        mProcessesOnHold.remove(app);
6072
6073        boolean badApp = false;
6074        boolean didSomething = false;
6075
6076        // See if the top visible activity is waiting to run in this process...
6077        if (normalMode) {
6078            try {
6079                if (mStackSupervisor.attachApplicationLocked(app)) {
6080                    didSomething = true;
6081                }
6082            } catch (Exception e) {
6083                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6084                badApp = true;
6085            }
6086        }
6087
6088        // Find any services that should be running in this process...
6089        if (!badApp) {
6090            try {
6091                didSomething |= mServices.attachApplicationLocked(app, processName);
6092            } catch (Exception e) {
6093                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6094                badApp = true;
6095            }
6096        }
6097
6098        // Check if a next-broadcast receiver is in this process...
6099        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6100            try {
6101                didSomething |= sendPendingBroadcastsLocked(app);
6102            } catch (Exception e) {
6103                // If the app died trying to launch the receiver we declare it 'bad'
6104                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6105                badApp = true;
6106            }
6107        }
6108
6109        // Check whether the next backup agent is in this process...
6110        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6111            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6112                    "New app is backup target, launching agent for " + app);
6113            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6114            try {
6115                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6116                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6117                        mBackupTarget.backupMode);
6118            } catch (Exception e) {
6119                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6120                badApp = true;
6121            }
6122        }
6123
6124        if (badApp) {
6125            app.kill("error during init", true);
6126            handleAppDiedLocked(app, false, true);
6127            return false;
6128        }
6129
6130        if (!didSomething) {
6131            updateOomAdjLocked();
6132        }
6133
6134        return true;
6135    }
6136
6137    @Override
6138    public final void attachApplication(IApplicationThread thread) {
6139        synchronized (this) {
6140            int callingPid = Binder.getCallingPid();
6141            final long origId = Binder.clearCallingIdentity();
6142            attachApplicationLocked(thread, callingPid);
6143            Binder.restoreCallingIdentity(origId);
6144        }
6145    }
6146
6147    @Override
6148    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6149        final long origId = Binder.clearCallingIdentity();
6150        synchronized (this) {
6151            ActivityStack stack = ActivityRecord.getStackLocked(token);
6152            if (stack != null) {
6153                ActivityRecord r =
6154                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6155                if (stopProfiling) {
6156                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6157                        try {
6158                            mProfileFd.close();
6159                        } catch (IOException e) {
6160                        }
6161                        clearProfilerLocked();
6162                    }
6163                }
6164            }
6165        }
6166        Binder.restoreCallingIdentity(origId);
6167    }
6168
6169    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6170        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6171                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6172    }
6173
6174    void enableScreenAfterBoot() {
6175        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6176                SystemClock.uptimeMillis());
6177        mWindowManager.enableScreenAfterBoot();
6178
6179        synchronized (this) {
6180            updateEventDispatchingLocked();
6181        }
6182    }
6183
6184    @Override
6185    public void showBootMessage(final CharSequence msg, final boolean always) {
6186        if (Binder.getCallingUid() != Process.myUid()) {
6187            // These days only the core system can call this, so apps can't get in
6188            // the way of what we show about running them.
6189        }
6190        mWindowManager.showBootMessage(msg, always);
6191    }
6192
6193    @Override
6194    public void keyguardWaitingForActivityDrawn() {
6195        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6196        final long token = Binder.clearCallingIdentity();
6197        try {
6198            synchronized (this) {
6199                if (DEBUG_LOCKSCREEN) logLockScreen("");
6200                mWindowManager.keyguardWaitingForActivityDrawn();
6201                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6202                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6203                    updateSleepIfNeededLocked();
6204                }
6205            }
6206        } finally {
6207            Binder.restoreCallingIdentity(token);
6208        }
6209    }
6210
6211    @Override
6212    public void keyguardGoingAway(boolean disableWindowAnimations,
6213            boolean keyguardGoingToNotificationShade) {
6214        enforceNotIsolatedCaller("keyguardGoingAway");
6215        final long token = Binder.clearCallingIdentity();
6216        try {
6217            synchronized (this) {
6218                if (DEBUG_LOCKSCREEN) logLockScreen("");
6219                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6220                        keyguardGoingToNotificationShade);
6221                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6222                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6223                    updateSleepIfNeededLocked();
6224                }
6225            }
6226        } finally {
6227            Binder.restoreCallingIdentity(token);
6228        }
6229    }
6230
6231    final void finishBooting() {
6232        synchronized (this) {
6233            if (!mBootAnimationComplete) {
6234                mCallFinishBooting = true;
6235                return;
6236            }
6237            mCallFinishBooting = false;
6238        }
6239
6240        ArraySet<String> completedIsas = new ArraySet<String>();
6241        for (String abi : Build.SUPPORTED_ABIS) {
6242            Process.establishZygoteConnectionForAbi(abi);
6243            final String instructionSet = VMRuntime.getInstructionSet(abi);
6244            if (!completedIsas.contains(instructionSet)) {
6245                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6246                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6247                }
6248                completedIsas.add(instructionSet);
6249            }
6250        }
6251
6252        IntentFilter pkgFilter = new IntentFilter();
6253        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6254        pkgFilter.addDataScheme("package");
6255        mContext.registerReceiver(new BroadcastReceiver() {
6256            @Override
6257            public void onReceive(Context context, Intent intent) {
6258                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6259                if (pkgs != null) {
6260                    for (String pkg : pkgs) {
6261                        synchronized (ActivityManagerService.this) {
6262                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6263                                    0, "query restart")) {
6264                                setResultCode(Activity.RESULT_OK);
6265                                return;
6266                            }
6267                        }
6268                    }
6269                }
6270            }
6271        }, pkgFilter);
6272
6273        IntentFilter dumpheapFilter = new IntentFilter();
6274        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6275        mContext.registerReceiver(new BroadcastReceiver() {
6276            @Override
6277            public void onReceive(Context context, Intent intent) {
6278                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6279                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6280                } else {
6281                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6282                }
6283            }
6284        }, dumpheapFilter);
6285
6286        // Let system services know.
6287        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6288
6289        synchronized (this) {
6290            // Ensure that any processes we had put on hold are now started
6291            // up.
6292            final int NP = mProcessesOnHold.size();
6293            if (NP > 0) {
6294                ArrayList<ProcessRecord> procs =
6295                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6296                for (int ip=0; ip<NP; ip++) {
6297                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6298                            + procs.get(ip));
6299                    startProcessLocked(procs.get(ip), "on-hold", null);
6300                }
6301            }
6302
6303            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6304                // Start looking for apps that are abusing wake locks.
6305                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6306                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6307                // Tell anyone interested that we are done booting!
6308                SystemProperties.set("sys.boot_completed", "1");
6309
6310                // And trigger dev.bootcomplete if we are not showing encryption progress
6311                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6312                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6313                    SystemProperties.set("dev.bootcomplete", "1");
6314                }
6315                for (int i=0; i<mStartedUsers.size(); i++) {
6316                    UserState uss = mStartedUsers.valueAt(i);
6317                    if (uss.mState == UserState.STATE_BOOTING) {
6318                        uss.mState = UserState.STATE_RUNNING;
6319                        final int userId = mStartedUsers.keyAt(i);
6320                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6321                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6322                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6323                        broadcastIntentLocked(null, null, intent, null,
6324                                new IIntentReceiver.Stub() {
6325                                    @Override
6326                                    public void performReceive(Intent intent, int resultCode,
6327                                            String data, Bundle extras, boolean ordered,
6328                                            boolean sticky, int sendingUser) {
6329                                        synchronized (ActivityManagerService.this) {
6330                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6331                                                    true, false);
6332                                        }
6333                                    }
6334                                },
6335                                0, null, null,
6336                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6337                                AppOpsManager.OP_NONE, null, true, false,
6338                                MY_PID, Process.SYSTEM_UID, userId);
6339                    }
6340                }
6341                scheduleStartProfilesLocked();
6342            }
6343        }
6344    }
6345
6346    @Override
6347    public void bootAnimationComplete() {
6348        final boolean callFinishBooting;
6349        synchronized (this) {
6350            callFinishBooting = mCallFinishBooting;
6351            mBootAnimationComplete = true;
6352        }
6353        if (callFinishBooting) {
6354            finishBooting();
6355        }
6356    }
6357
6358    final void ensureBootCompleted() {
6359        boolean booting;
6360        boolean enableScreen;
6361        synchronized (this) {
6362            booting = mBooting;
6363            mBooting = false;
6364            enableScreen = !mBooted;
6365            mBooted = true;
6366        }
6367
6368        if (booting) {
6369            finishBooting();
6370        }
6371
6372        if (enableScreen) {
6373            enableScreenAfterBoot();
6374        }
6375    }
6376
6377    @Override
6378    public final void activityResumed(IBinder token) {
6379        final long origId = Binder.clearCallingIdentity();
6380        synchronized(this) {
6381            ActivityStack stack = ActivityRecord.getStackLocked(token);
6382            if (stack != null) {
6383                ActivityRecord.activityResumedLocked(token);
6384            }
6385        }
6386        Binder.restoreCallingIdentity(origId);
6387    }
6388
6389    @Override
6390    public final void activityPaused(IBinder token) {
6391        final long origId = Binder.clearCallingIdentity();
6392        synchronized(this) {
6393            ActivityStack stack = ActivityRecord.getStackLocked(token);
6394            if (stack != null) {
6395                stack.activityPausedLocked(token, false);
6396            }
6397        }
6398        Binder.restoreCallingIdentity(origId);
6399    }
6400
6401    @Override
6402    public final void activityStopped(IBinder token, Bundle icicle,
6403            PersistableBundle persistentState, CharSequence description) {
6404        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6405
6406        // Refuse possible leaked file descriptors
6407        if (icicle != null && icicle.hasFileDescriptors()) {
6408            throw new IllegalArgumentException("File descriptors passed in Bundle");
6409        }
6410
6411        final long origId = Binder.clearCallingIdentity();
6412
6413        synchronized (this) {
6414            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6415            if (r != null) {
6416                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6417            }
6418        }
6419
6420        trimApplications();
6421
6422        Binder.restoreCallingIdentity(origId);
6423    }
6424
6425    @Override
6426    public final void activityDestroyed(IBinder token) {
6427        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6428        synchronized (this) {
6429            ActivityStack stack = ActivityRecord.getStackLocked(token);
6430            if (stack != null) {
6431                stack.activityDestroyedLocked(token, "activityDestroyed");
6432            }
6433        }
6434    }
6435
6436    @Override
6437    public final void backgroundResourcesReleased(IBinder token) {
6438        final long origId = Binder.clearCallingIdentity();
6439        try {
6440            synchronized (this) {
6441                ActivityStack stack = ActivityRecord.getStackLocked(token);
6442                if (stack != null) {
6443                    stack.backgroundResourcesReleased();
6444                }
6445            }
6446        } finally {
6447            Binder.restoreCallingIdentity(origId);
6448        }
6449    }
6450
6451    @Override
6452    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6453        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6454    }
6455
6456    @Override
6457    public final void notifyEnterAnimationComplete(IBinder token) {
6458        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6459    }
6460
6461    @Override
6462    public String getCallingPackage(IBinder token) {
6463        synchronized (this) {
6464            ActivityRecord r = getCallingRecordLocked(token);
6465            return r != null ? r.info.packageName : null;
6466        }
6467    }
6468
6469    @Override
6470    public ComponentName getCallingActivity(IBinder token) {
6471        synchronized (this) {
6472            ActivityRecord r = getCallingRecordLocked(token);
6473            return r != null ? r.intent.getComponent() : null;
6474        }
6475    }
6476
6477    private ActivityRecord getCallingRecordLocked(IBinder token) {
6478        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6479        if (r == null) {
6480            return null;
6481        }
6482        return r.resultTo;
6483    }
6484
6485    @Override
6486    public ComponentName getActivityClassForToken(IBinder token) {
6487        synchronized(this) {
6488            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6489            if (r == null) {
6490                return null;
6491            }
6492            return r.intent.getComponent();
6493        }
6494    }
6495
6496    @Override
6497    public String getPackageForToken(IBinder token) {
6498        synchronized(this) {
6499            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6500            if (r == null) {
6501                return null;
6502            }
6503            return r.packageName;
6504        }
6505    }
6506
6507    @Override
6508    public IIntentSender getIntentSender(int type,
6509            String packageName, IBinder token, String resultWho,
6510            int requestCode, Intent[] intents, String[] resolvedTypes,
6511            int flags, Bundle options, int userId) {
6512        enforceNotIsolatedCaller("getIntentSender");
6513        // Refuse possible leaked file descriptors
6514        if (intents != null) {
6515            if (intents.length < 1) {
6516                throw new IllegalArgumentException("Intents array length must be >= 1");
6517            }
6518            for (int i=0; i<intents.length; i++) {
6519                Intent intent = intents[i];
6520                if (intent != null) {
6521                    if (intent.hasFileDescriptors()) {
6522                        throw new IllegalArgumentException("File descriptors passed in Intent");
6523                    }
6524                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6525                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6526                        throw new IllegalArgumentException(
6527                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6528                    }
6529                    intents[i] = new Intent(intent);
6530                }
6531            }
6532            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6533                throw new IllegalArgumentException(
6534                        "Intent array length does not match resolvedTypes length");
6535            }
6536        }
6537        if (options != null) {
6538            if (options.hasFileDescriptors()) {
6539                throw new IllegalArgumentException("File descriptors passed in options");
6540            }
6541        }
6542
6543        synchronized(this) {
6544            int callingUid = Binder.getCallingUid();
6545            int origUserId = userId;
6546            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6547                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6548                    ALLOW_NON_FULL, "getIntentSender", null);
6549            if (origUserId == UserHandle.USER_CURRENT) {
6550                // We don't want to evaluate this until the pending intent is
6551                // actually executed.  However, we do want to always do the
6552                // security checking for it above.
6553                userId = UserHandle.USER_CURRENT;
6554            }
6555            try {
6556                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6557                    int uid = AppGlobals.getPackageManager()
6558                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6559                    if (!UserHandle.isSameApp(callingUid, uid)) {
6560                        String msg = "Permission Denial: getIntentSender() from pid="
6561                            + Binder.getCallingPid()
6562                            + ", uid=" + Binder.getCallingUid()
6563                            + ", (need uid=" + uid + ")"
6564                            + " is not allowed to send as package " + packageName;
6565                        Slog.w(TAG, msg);
6566                        throw new SecurityException(msg);
6567                    }
6568                }
6569
6570                return getIntentSenderLocked(type, packageName, callingUid, userId,
6571                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6572
6573            } catch (RemoteException e) {
6574                throw new SecurityException(e);
6575            }
6576        }
6577    }
6578
6579    IIntentSender getIntentSenderLocked(int type, String packageName,
6580            int callingUid, int userId, IBinder token, String resultWho,
6581            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6582            Bundle options) {
6583        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6584        ActivityRecord activity = null;
6585        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6586            activity = ActivityRecord.isInStackLocked(token);
6587            if (activity == null) {
6588                return null;
6589            }
6590            if (activity.finishing) {
6591                return null;
6592            }
6593        }
6594
6595        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6596        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6597        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6598        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6599                |PendingIntent.FLAG_UPDATE_CURRENT);
6600
6601        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6602                type, packageName, activity, resultWho,
6603                requestCode, intents, resolvedTypes, flags, options, userId);
6604        WeakReference<PendingIntentRecord> ref;
6605        ref = mIntentSenderRecords.get(key);
6606        PendingIntentRecord rec = ref != null ? ref.get() : null;
6607        if (rec != null) {
6608            if (!cancelCurrent) {
6609                if (updateCurrent) {
6610                    if (rec.key.requestIntent != null) {
6611                        rec.key.requestIntent.replaceExtras(intents != null ?
6612                                intents[intents.length - 1] : null);
6613                    }
6614                    if (intents != null) {
6615                        intents[intents.length-1] = rec.key.requestIntent;
6616                        rec.key.allIntents = intents;
6617                        rec.key.allResolvedTypes = resolvedTypes;
6618                    } else {
6619                        rec.key.allIntents = null;
6620                        rec.key.allResolvedTypes = null;
6621                    }
6622                }
6623                return rec;
6624            }
6625            rec.canceled = true;
6626            mIntentSenderRecords.remove(key);
6627        }
6628        if (noCreate) {
6629            return rec;
6630        }
6631        rec = new PendingIntentRecord(this, key, callingUid);
6632        mIntentSenderRecords.put(key, rec.ref);
6633        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6634            if (activity.pendingResults == null) {
6635                activity.pendingResults
6636                        = new HashSet<WeakReference<PendingIntentRecord>>();
6637            }
6638            activity.pendingResults.add(rec.ref);
6639        }
6640        return rec;
6641    }
6642
6643    @Override
6644    public void cancelIntentSender(IIntentSender sender) {
6645        if (!(sender instanceof PendingIntentRecord)) {
6646            return;
6647        }
6648        synchronized(this) {
6649            PendingIntentRecord rec = (PendingIntentRecord)sender;
6650            try {
6651                int uid = AppGlobals.getPackageManager()
6652                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6653                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6654                    String msg = "Permission Denial: cancelIntentSender() from pid="
6655                        + Binder.getCallingPid()
6656                        + ", uid=" + Binder.getCallingUid()
6657                        + " is not allowed to cancel packges "
6658                        + rec.key.packageName;
6659                    Slog.w(TAG, msg);
6660                    throw new SecurityException(msg);
6661                }
6662            } catch (RemoteException e) {
6663                throw new SecurityException(e);
6664            }
6665            cancelIntentSenderLocked(rec, true);
6666        }
6667    }
6668
6669    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6670        rec.canceled = true;
6671        mIntentSenderRecords.remove(rec.key);
6672        if (cleanActivity && rec.key.activity != null) {
6673            rec.key.activity.pendingResults.remove(rec.ref);
6674        }
6675    }
6676
6677    @Override
6678    public String getPackageForIntentSender(IIntentSender pendingResult) {
6679        if (!(pendingResult instanceof PendingIntentRecord)) {
6680            return null;
6681        }
6682        try {
6683            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6684            return res.key.packageName;
6685        } catch (ClassCastException e) {
6686        }
6687        return null;
6688    }
6689
6690    @Override
6691    public int getUidForIntentSender(IIntentSender sender) {
6692        if (sender instanceof PendingIntentRecord) {
6693            try {
6694                PendingIntentRecord res = (PendingIntentRecord)sender;
6695                return res.uid;
6696            } catch (ClassCastException e) {
6697            }
6698        }
6699        return -1;
6700    }
6701
6702    @Override
6703    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6704        if (!(pendingResult instanceof PendingIntentRecord)) {
6705            return false;
6706        }
6707        try {
6708            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6709            if (res.key.allIntents == null) {
6710                return false;
6711            }
6712            for (int i=0; i<res.key.allIntents.length; i++) {
6713                Intent intent = res.key.allIntents[i];
6714                if (intent.getPackage() != null && intent.getComponent() != null) {
6715                    return false;
6716                }
6717            }
6718            return true;
6719        } catch (ClassCastException e) {
6720        }
6721        return false;
6722    }
6723
6724    @Override
6725    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6726        if (!(pendingResult instanceof PendingIntentRecord)) {
6727            return false;
6728        }
6729        try {
6730            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6731            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6732                return true;
6733            }
6734            return false;
6735        } catch (ClassCastException e) {
6736        }
6737        return false;
6738    }
6739
6740    @Override
6741    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6742        if (!(pendingResult instanceof PendingIntentRecord)) {
6743            return null;
6744        }
6745        try {
6746            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6747            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6748        } catch (ClassCastException e) {
6749        }
6750        return null;
6751    }
6752
6753    @Override
6754    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6755        if (!(pendingResult instanceof PendingIntentRecord)) {
6756            return null;
6757        }
6758        try {
6759            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6760            synchronized (this) {
6761                return getTagForIntentSenderLocked(res, prefix);
6762            }
6763        } catch (ClassCastException e) {
6764        }
6765        return null;
6766    }
6767
6768    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6769        final Intent intent = res.key.requestIntent;
6770        if (intent != null) {
6771            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6772                    || res.lastTagPrefix.equals(prefix))) {
6773                return res.lastTag;
6774            }
6775            res.lastTagPrefix = prefix;
6776            final StringBuilder sb = new StringBuilder(128);
6777            if (prefix != null) {
6778                sb.append(prefix);
6779            }
6780            if (intent.getAction() != null) {
6781                sb.append(intent.getAction());
6782            } else if (intent.getComponent() != null) {
6783                intent.getComponent().appendShortString(sb);
6784            } else {
6785                sb.append("?");
6786            }
6787            return res.lastTag = sb.toString();
6788        }
6789        return null;
6790    }
6791
6792    @Override
6793    public void setProcessLimit(int max) {
6794        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6795                "setProcessLimit()");
6796        synchronized (this) {
6797            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6798            mProcessLimitOverride = max;
6799        }
6800        trimApplications();
6801    }
6802
6803    @Override
6804    public int getProcessLimit() {
6805        synchronized (this) {
6806            return mProcessLimitOverride;
6807        }
6808    }
6809
6810    void foregroundTokenDied(ForegroundToken token) {
6811        synchronized (ActivityManagerService.this) {
6812            synchronized (mPidsSelfLocked) {
6813                ForegroundToken cur
6814                    = mForegroundProcesses.get(token.pid);
6815                if (cur != token) {
6816                    return;
6817                }
6818                mForegroundProcesses.remove(token.pid);
6819                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6820                if (pr == null) {
6821                    return;
6822                }
6823                pr.forcingToForeground = null;
6824                updateProcessForegroundLocked(pr, false, false);
6825            }
6826            updateOomAdjLocked();
6827        }
6828    }
6829
6830    @Override
6831    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6832        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6833                "setProcessForeground()");
6834        synchronized(this) {
6835            boolean changed = false;
6836
6837            synchronized (mPidsSelfLocked) {
6838                ProcessRecord pr = mPidsSelfLocked.get(pid);
6839                if (pr == null && isForeground) {
6840                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6841                    return;
6842                }
6843                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6844                if (oldToken != null) {
6845                    oldToken.token.unlinkToDeath(oldToken, 0);
6846                    mForegroundProcesses.remove(pid);
6847                    if (pr != null) {
6848                        pr.forcingToForeground = null;
6849                    }
6850                    changed = true;
6851                }
6852                if (isForeground && token != null) {
6853                    ForegroundToken newToken = new ForegroundToken() {
6854                        @Override
6855                        public void binderDied() {
6856                            foregroundTokenDied(this);
6857                        }
6858                    };
6859                    newToken.pid = pid;
6860                    newToken.token = token;
6861                    try {
6862                        token.linkToDeath(newToken, 0);
6863                        mForegroundProcesses.put(pid, newToken);
6864                        pr.forcingToForeground = token;
6865                        changed = true;
6866                    } catch (RemoteException e) {
6867                        // If the process died while doing this, we will later
6868                        // do the cleanup with the process death link.
6869                    }
6870                }
6871            }
6872
6873            if (changed) {
6874                updateOomAdjLocked();
6875            }
6876        }
6877    }
6878
6879    // =========================================================
6880    // PROCESS INFO
6881    // =========================================================
6882
6883    static class ProcessInfoService extends IProcessInfoService.Stub {
6884        final ActivityManagerService mActivityManagerService;
6885        ProcessInfoService(ActivityManagerService activityManagerService) {
6886            mActivityManagerService = activityManagerService;
6887        }
6888
6889        @Override
6890        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6891            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6892        }
6893    }
6894
6895    /**
6896     * For each PID in the given input array, write the current process state
6897     * for that process into the output array, or -1 to indicate that no
6898     * process with the given PID exists.
6899     */
6900    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6901        if (pids == null) {
6902            throw new NullPointerException("pids");
6903        } else if (states == null) {
6904            throw new NullPointerException("states");
6905        } else if (pids.length != states.length) {
6906            throw new IllegalArgumentException("input and output arrays have different lengths!");
6907        }
6908
6909        synchronized (mPidsSelfLocked) {
6910            for (int i = 0; i < pids.length; i++) {
6911                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6912                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6913                        pr.curProcState;
6914            }
6915        }
6916    }
6917
6918    // =========================================================
6919    // PERMISSIONS
6920    // =========================================================
6921
6922    static class PermissionController extends IPermissionController.Stub {
6923        ActivityManagerService mActivityManagerService;
6924        PermissionController(ActivityManagerService activityManagerService) {
6925            mActivityManagerService = activityManagerService;
6926        }
6927
6928        @Override
6929        public boolean checkPermission(String permission, int pid, int uid) {
6930            return mActivityManagerService.checkPermission(permission, pid,
6931                    uid) == PackageManager.PERMISSION_GRANTED;
6932        }
6933
6934        @Override
6935        public String[] getPackagesForUid(int uid) {
6936            return mActivityManagerService.mContext.getPackageManager()
6937                    .getPackagesForUid(uid);
6938        }
6939
6940        @Override
6941        public boolean isRuntimePermission(String permission) {
6942            try {
6943                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
6944                        .getPermissionInfo(permission, 0);
6945                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
6946            } catch (NameNotFoundException nnfe) {
6947                Slog.e(TAG, "No such permission: "+ permission, nnfe);
6948            }
6949            return false;
6950        }
6951    }
6952
6953    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6954        @Override
6955        public int checkComponentPermission(String permission, int pid, int uid,
6956                int owningUid, boolean exported) {
6957            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6958                    owningUid, exported);
6959        }
6960
6961        @Override
6962        public Object getAMSLock() {
6963            return ActivityManagerService.this;
6964        }
6965    }
6966
6967    /**
6968     * This can be called with or without the global lock held.
6969     */
6970    int checkComponentPermission(String permission, int pid, int uid,
6971            int owningUid, boolean exported) {
6972        if (pid == MY_PID) {
6973            return PackageManager.PERMISSION_GRANTED;
6974        }
6975        return ActivityManager.checkComponentPermission(permission, uid,
6976                owningUid, exported);
6977    }
6978
6979    /**
6980     * As the only public entry point for permissions checking, this method
6981     * can enforce the semantic that requesting a check on a null global
6982     * permission is automatically denied.  (Internally a null permission
6983     * string is used when calling {@link #checkComponentPermission} in cases
6984     * when only uid-based security is needed.)
6985     *
6986     * This can be called with or without the global lock held.
6987     */
6988    @Override
6989    public int checkPermission(String permission, int pid, int uid) {
6990        if (permission == null) {
6991            return PackageManager.PERMISSION_DENIED;
6992        }
6993        return checkComponentPermission(permission, pid, uid, -1, true);
6994    }
6995
6996    @Override
6997    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6998        if (permission == null) {
6999            return PackageManager.PERMISSION_DENIED;
7000        }
7001
7002        // We might be performing an operation on behalf of an indirect binder
7003        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7004        // client identity accordingly before proceeding.
7005        Identity tlsIdentity = sCallerIdentity.get();
7006        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7007            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7008                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7009            uid = tlsIdentity.uid;
7010            pid = tlsIdentity.pid;
7011        }
7012
7013        return checkComponentPermission(permission, pid, uid, -1, true);
7014    }
7015
7016    /**
7017     * Binder IPC calls go through the public entry point.
7018     * This can be called with or without the global lock held.
7019     */
7020    int checkCallingPermission(String permission) {
7021        return checkPermission(permission,
7022                Binder.getCallingPid(),
7023                UserHandle.getAppId(Binder.getCallingUid()));
7024    }
7025
7026    /**
7027     * This can be called with or without the global lock held.
7028     */
7029    void enforceCallingPermission(String permission, String func) {
7030        if (checkCallingPermission(permission)
7031                == PackageManager.PERMISSION_GRANTED) {
7032            return;
7033        }
7034
7035        String msg = "Permission Denial: " + func + " from pid="
7036                + Binder.getCallingPid()
7037                + ", uid=" + Binder.getCallingUid()
7038                + " requires " + permission;
7039        Slog.w(TAG, msg);
7040        throw new SecurityException(msg);
7041    }
7042
7043    /**
7044     * Determine if UID is holding permissions required to access {@link Uri} in
7045     * the given {@link ProviderInfo}. Final permission checking is always done
7046     * in {@link ContentProvider}.
7047     */
7048    private final boolean checkHoldingPermissionsLocked(
7049            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7050        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7051                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7052        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7053            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7054                    != PERMISSION_GRANTED) {
7055                return false;
7056            }
7057        }
7058        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7059    }
7060
7061    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7062            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7063        if (pi.applicationInfo.uid == uid) {
7064            return true;
7065        } else if (!pi.exported) {
7066            return false;
7067        }
7068
7069        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7070        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7071        try {
7072            // check if target holds top-level <provider> permissions
7073            if (!readMet && pi.readPermission != null && considerUidPermissions
7074                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7075                readMet = true;
7076            }
7077            if (!writeMet && pi.writePermission != null && considerUidPermissions
7078                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7079                writeMet = true;
7080            }
7081
7082            // track if unprotected read/write is allowed; any denied
7083            // <path-permission> below removes this ability
7084            boolean allowDefaultRead = pi.readPermission == null;
7085            boolean allowDefaultWrite = pi.writePermission == null;
7086
7087            // check if target holds any <path-permission> that match uri
7088            final PathPermission[] pps = pi.pathPermissions;
7089            if (pps != null) {
7090                final String path = grantUri.uri.getPath();
7091                int i = pps.length;
7092                while (i > 0 && (!readMet || !writeMet)) {
7093                    i--;
7094                    PathPermission pp = pps[i];
7095                    if (pp.match(path)) {
7096                        if (!readMet) {
7097                            final String pprperm = pp.getReadPermission();
7098                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7099                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7100                                    + ": match=" + pp.match(path)
7101                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7102                            if (pprperm != null) {
7103                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7104                                        == PERMISSION_GRANTED) {
7105                                    readMet = true;
7106                                } else {
7107                                    allowDefaultRead = false;
7108                                }
7109                            }
7110                        }
7111                        if (!writeMet) {
7112                            final String ppwperm = pp.getWritePermission();
7113                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7114                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7115                                    + ": match=" + pp.match(path)
7116                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7117                            if (ppwperm != null) {
7118                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7119                                        == PERMISSION_GRANTED) {
7120                                    writeMet = true;
7121                                } else {
7122                                    allowDefaultWrite = false;
7123                                }
7124                            }
7125                        }
7126                    }
7127                }
7128            }
7129
7130            // grant unprotected <provider> read/write, if not blocked by
7131            // <path-permission> above
7132            if (allowDefaultRead) readMet = true;
7133            if (allowDefaultWrite) writeMet = true;
7134
7135        } catch (RemoteException e) {
7136            return false;
7137        }
7138
7139        return readMet && writeMet;
7140    }
7141
7142    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7143        ProviderInfo pi = null;
7144        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7145        if (cpr != null) {
7146            pi = cpr.info;
7147        } else {
7148            try {
7149                pi = AppGlobals.getPackageManager().resolveContentProvider(
7150                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7151            } catch (RemoteException ex) {
7152            }
7153        }
7154        return pi;
7155    }
7156
7157    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7158        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7159        if (targetUris != null) {
7160            return targetUris.get(grantUri);
7161        }
7162        return null;
7163    }
7164
7165    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7166            String targetPkg, int targetUid, GrantUri grantUri) {
7167        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7168        if (targetUris == null) {
7169            targetUris = Maps.newArrayMap();
7170            mGrantedUriPermissions.put(targetUid, targetUris);
7171        }
7172
7173        UriPermission perm = targetUris.get(grantUri);
7174        if (perm == null) {
7175            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7176            targetUris.put(grantUri, perm);
7177        }
7178
7179        return perm;
7180    }
7181
7182    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7183            final int modeFlags) {
7184        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7185        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7186                : UriPermission.STRENGTH_OWNED;
7187
7188        // Root gets to do everything.
7189        if (uid == 0) {
7190            return true;
7191        }
7192
7193        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7194        if (perms == null) return false;
7195
7196        // First look for exact match
7197        final UriPermission exactPerm = perms.get(grantUri);
7198        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7199            return true;
7200        }
7201
7202        // No exact match, look for prefixes
7203        final int N = perms.size();
7204        for (int i = 0; i < N; i++) {
7205            final UriPermission perm = perms.valueAt(i);
7206            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7207                    && perm.getStrength(modeFlags) >= minStrength) {
7208                return true;
7209            }
7210        }
7211
7212        return false;
7213    }
7214
7215    /**
7216     * @param uri This uri must NOT contain an embedded userId.
7217     * @param userId The userId in which the uri is to be resolved.
7218     */
7219    @Override
7220    public int checkUriPermission(Uri uri, int pid, int uid,
7221            final int modeFlags, int userId, IBinder callerToken) {
7222        enforceNotIsolatedCaller("checkUriPermission");
7223
7224        // Another redirected-binder-call permissions check as in
7225        // {@link checkPermissionWithToken}.
7226        Identity tlsIdentity = sCallerIdentity.get();
7227        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7228            uid = tlsIdentity.uid;
7229            pid = tlsIdentity.pid;
7230        }
7231
7232        // Our own process gets to do everything.
7233        if (pid == MY_PID) {
7234            return PackageManager.PERMISSION_GRANTED;
7235        }
7236        synchronized (this) {
7237            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7238                    ? PackageManager.PERMISSION_GRANTED
7239                    : PackageManager.PERMISSION_DENIED;
7240        }
7241    }
7242
7243    /**
7244     * Check if the targetPkg can be granted permission to access uri by
7245     * the callingUid using the given modeFlags.  Throws a security exception
7246     * if callingUid is not allowed to do this.  Returns the uid of the target
7247     * if the URI permission grant should be performed; returns -1 if it is not
7248     * needed (for example targetPkg already has permission to access the URI).
7249     * If you already know the uid of the target, you can supply it in
7250     * lastTargetUid else set that to -1.
7251     */
7252    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7253            final int modeFlags, int lastTargetUid) {
7254        if (!Intent.isAccessUriMode(modeFlags)) {
7255            return -1;
7256        }
7257
7258        if (targetPkg != null) {
7259            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7260                    "Checking grant " + targetPkg + " permission to " + grantUri);
7261        }
7262
7263        final IPackageManager pm = AppGlobals.getPackageManager();
7264
7265        // If this is not a content: uri, we can't do anything with it.
7266        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7267            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7268                    "Can't grant URI permission for non-content URI: " + grantUri);
7269            return -1;
7270        }
7271
7272        final String authority = grantUri.uri.getAuthority();
7273        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7274        if (pi == null) {
7275            Slog.w(TAG, "No content provider found for permission check: " +
7276                    grantUri.uri.toSafeString());
7277            return -1;
7278        }
7279
7280        int targetUid = lastTargetUid;
7281        if (targetUid < 0 && targetPkg != null) {
7282            try {
7283                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7284                if (targetUid < 0) {
7285                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7286                            "Can't grant URI permission no uid for: " + targetPkg);
7287                    return -1;
7288                }
7289            } catch (RemoteException ex) {
7290                return -1;
7291            }
7292        }
7293
7294        if (targetUid >= 0) {
7295            // First...  does the target actually need this permission?
7296            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7297                // No need to grant the target this permission.
7298                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7299                        "Target " + targetPkg + " already has full permission to " + grantUri);
7300                return -1;
7301            }
7302        } else {
7303            // First...  there is no target package, so can anyone access it?
7304            boolean allowed = pi.exported;
7305            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7306                if (pi.readPermission != null) {
7307                    allowed = false;
7308                }
7309            }
7310            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7311                if (pi.writePermission != null) {
7312                    allowed = false;
7313                }
7314            }
7315            if (allowed) {
7316                return -1;
7317            }
7318        }
7319
7320        /* There is a special cross user grant if:
7321         * - The target is on another user.
7322         * - Apps on the current user can access the uri without any uid permissions.
7323         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7324         * grant uri permissions.
7325         */
7326        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7327                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7328                modeFlags, false /*without considering the uid permissions*/);
7329
7330        // Second...  is the provider allowing granting of URI permissions?
7331        if (!specialCrossUserGrant) {
7332            if (!pi.grantUriPermissions) {
7333                throw new SecurityException("Provider " + pi.packageName
7334                        + "/" + pi.name
7335                        + " does not allow granting of Uri permissions (uri "
7336                        + grantUri + ")");
7337            }
7338            if (pi.uriPermissionPatterns != null) {
7339                final int N = pi.uriPermissionPatterns.length;
7340                boolean allowed = false;
7341                for (int i=0; i<N; i++) {
7342                    if (pi.uriPermissionPatterns[i] != null
7343                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7344                        allowed = true;
7345                        break;
7346                    }
7347                }
7348                if (!allowed) {
7349                    throw new SecurityException("Provider " + pi.packageName
7350                            + "/" + pi.name
7351                            + " does not allow granting of permission to path of Uri "
7352                            + grantUri);
7353                }
7354            }
7355        }
7356
7357        // Third...  does the caller itself have permission to access
7358        // this uri?
7359        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7360            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7361                // Require they hold a strong enough Uri permission
7362                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7363                    throw new SecurityException("Uid " + callingUid
7364                            + " does not have permission to uri " + grantUri);
7365                }
7366            }
7367        }
7368        return targetUid;
7369    }
7370
7371    /**
7372     * @param uri This uri must NOT contain an embedded userId.
7373     * @param userId The userId in which the uri is to be resolved.
7374     */
7375    @Override
7376    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7377            final int modeFlags, int userId) {
7378        enforceNotIsolatedCaller("checkGrantUriPermission");
7379        synchronized(this) {
7380            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7381                    new GrantUri(userId, uri, false), modeFlags, -1);
7382        }
7383    }
7384
7385    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7386            final int modeFlags, UriPermissionOwner owner) {
7387        if (!Intent.isAccessUriMode(modeFlags)) {
7388            return;
7389        }
7390
7391        // So here we are: the caller has the assumed permission
7392        // to the uri, and the target doesn't.  Let's now give this to
7393        // the target.
7394
7395        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7396                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7397
7398        final String authority = grantUri.uri.getAuthority();
7399        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7400        if (pi == null) {
7401            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7402            return;
7403        }
7404
7405        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7406            grantUri.prefix = true;
7407        }
7408        final UriPermission perm = findOrCreateUriPermissionLocked(
7409                pi.packageName, targetPkg, targetUid, grantUri);
7410        perm.grantModes(modeFlags, owner);
7411    }
7412
7413    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7414            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7415        if (targetPkg == null) {
7416            throw new NullPointerException("targetPkg");
7417        }
7418        int targetUid;
7419        final IPackageManager pm = AppGlobals.getPackageManager();
7420        try {
7421            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7422        } catch (RemoteException ex) {
7423            return;
7424        }
7425
7426        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7427                targetUid);
7428        if (targetUid < 0) {
7429            return;
7430        }
7431
7432        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7433                owner);
7434    }
7435
7436    static class NeededUriGrants extends ArrayList<GrantUri> {
7437        final String targetPkg;
7438        final int targetUid;
7439        final int flags;
7440
7441        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7442            this.targetPkg = targetPkg;
7443            this.targetUid = targetUid;
7444            this.flags = flags;
7445        }
7446    }
7447
7448    /**
7449     * Like checkGrantUriPermissionLocked, but takes an Intent.
7450     */
7451    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7452            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7453        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7454                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7455                + " clip=" + (intent != null ? intent.getClipData() : null)
7456                + " from " + intent + "; flags=0x"
7457                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7458
7459        if (targetPkg == null) {
7460            throw new NullPointerException("targetPkg");
7461        }
7462
7463        if (intent == null) {
7464            return null;
7465        }
7466        Uri data = intent.getData();
7467        ClipData clip = intent.getClipData();
7468        if (data == null && clip == null) {
7469            return null;
7470        }
7471        // Default userId for uris in the intent (if they don't specify it themselves)
7472        int contentUserHint = intent.getContentUserHint();
7473        if (contentUserHint == UserHandle.USER_CURRENT) {
7474            contentUserHint = UserHandle.getUserId(callingUid);
7475        }
7476        final IPackageManager pm = AppGlobals.getPackageManager();
7477        int targetUid;
7478        if (needed != null) {
7479            targetUid = needed.targetUid;
7480        } else {
7481            try {
7482                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7483            } catch (RemoteException ex) {
7484                return null;
7485            }
7486            if (targetUid < 0) {
7487                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7488                        "Can't grant URI permission no uid for: " + targetPkg
7489                        + " on user " + targetUserId);
7490                return null;
7491            }
7492        }
7493        if (data != null) {
7494            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7495            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7496                    targetUid);
7497            if (targetUid > 0) {
7498                if (needed == null) {
7499                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7500                }
7501                needed.add(grantUri);
7502            }
7503        }
7504        if (clip != null) {
7505            for (int i=0; i<clip.getItemCount(); i++) {
7506                Uri uri = clip.getItemAt(i).getUri();
7507                if (uri != null) {
7508                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7509                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7510                            targetUid);
7511                    if (targetUid > 0) {
7512                        if (needed == null) {
7513                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7514                        }
7515                        needed.add(grantUri);
7516                    }
7517                } else {
7518                    Intent clipIntent = clip.getItemAt(i).getIntent();
7519                    if (clipIntent != null) {
7520                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7521                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7522                        if (newNeeded != null) {
7523                            needed = newNeeded;
7524                        }
7525                    }
7526                }
7527            }
7528        }
7529
7530        return needed;
7531    }
7532
7533    /**
7534     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7535     */
7536    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7537            UriPermissionOwner owner) {
7538        if (needed != null) {
7539            for (int i=0; i<needed.size(); i++) {
7540                GrantUri grantUri = needed.get(i);
7541                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7542                        grantUri, needed.flags, owner);
7543            }
7544        }
7545    }
7546
7547    void grantUriPermissionFromIntentLocked(int callingUid,
7548            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7549        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7550                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7551        if (needed == null) {
7552            return;
7553        }
7554
7555        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7556    }
7557
7558    /**
7559     * @param uri This uri must NOT contain an embedded userId.
7560     * @param userId The userId in which the uri is to be resolved.
7561     */
7562    @Override
7563    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7564            final int modeFlags, int userId) {
7565        enforceNotIsolatedCaller("grantUriPermission");
7566        GrantUri grantUri = new GrantUri(userId, uri, false);
7567        synchronized(this) {
7568            final ProcessRecord r = getRecordForAppLocked(caller);
7569            if (r == null) {
7570                throw new SecurityException("Unable to find app for caller "
7571                        + caller
7572                        + " when granting permission to uri " + grantUri);
7573            }
7574            if (targetPkg == null) {
7575                throw new IllegalArgumentException("null target");
7576            }
7577            if (grantUri == null) {
7578                throw new IllegalArgumentException("null uri");
7579            }
7580
7581            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7582                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7583                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7584                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7585
7586            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7587                    UserHandle.getUserId(r.uid));
7588        }
7589    }
7590
7591    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7592        if (perm.modeFlags == 0) {
7593            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7594                    perm.targetUid);
7595            if (perms != null) {
7596                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7597                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7598
7599                perms.remove(perm.uri);
7600                if (perms.isEmpty()) {
7601                    mGrantedUriPermissions.remove(perm.targetUid);
7602                }
7603            }
7604        }
7605    }
7606
7607    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7608        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7609                "Revoking all granted permissions to " + grantUri);
7610
7611        final IPackageManager pm = AppGlobals.getPackageManager();
7612        final String authority = grantUri.uri.getAuthority();
7613        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7614        if (pi == null) {
7615            Slog.w(TAG, "No content provider found for permission revoke: "
7616                    + grantUri.toSafeString());
7617            return;
7618        }
7619
7620        // Does the caller have this permission on the URI?
7621        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7622            // If they don't have direct access to the URI, then revoke any
7623            // ownerless URI permissions that have been granted to them.
7624            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7625            if (perms != null) {
7626                boolean persistChanged = false;
7627                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7628                    final UriPermission perm = it.next();
7629                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7630                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7631                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7632                                "Revoking non-owned " + perm.targetUid
7633                                + " permission to " + perm.uri);
7634                        persistChanged |= perm.revokeModes(
7635                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7636                        if (perm.modeFlags == 0) {
7637                            it.remove();
7638                        }
7639                    }
7640                }
7641                if (perms.isEmpty()) {
7642                    mGrantedUriPermissions.remove(callingUid);
7643                }
7644                if (persistChanged) {
7645                    schedulePersistUriGrants();
7646                }
7647            }
7648            return;
7649        }
7650
7651        boolean persistChanged = false;
7652
7653        // Go through all of the permissions and remove any that match.
7654        int N = mGrantedUriPermissions.size();
7655        for (int i = 0; i < N; i++) {
7656            final int targetUid = mGrantedUriPermissions.keyAt(i);
7657            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7658
7659            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7660                final UriPermission perm = it.next();
7661                if (perm.uri.sourceUserId == grantUri.sourceUserId
7662                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7663                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7664                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7665                    persistChanged |= perm.revokeModes(
7666                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7667                    if (perm.modeFlags == 0) {
7668                        it.remove();
7669                    }
7670                }
7671            }
7672
7673            if (perms.isEmpty()) {
7674                mGrantedUriPermissions.remove(targetUid);
7675                N--;
7676                i--;
7677            }
7678        }
7679
7680        if (persistChanged) {
7681            schedulePersistUriGrants();
7682        }
7683    }
7684
7685    /**
7686     * @param uri This uri must NOT contain an embedded userId.
7687     * @param userId The userId in which the uri is to be resolved.
7688     */
7689    @Override
7690    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7691            int userId) {
7692        enforceNotIsolatedCaller("revokeUriPermission");
7693        synchronized(this) {
7694            final ProcessRecord r = getRecordForAppLocked(caller);
7695            if (r == null) {
7696                throw new SecurityException("Unable to find app for caller "
7697                        + caller
7698                        + " when revoking permission to uri " + uri);
7699            }
7700            if (uri == null) {
7701                Slog.w(TAG, "revokeUriPermission: null uri");
7702                return;
7703            }
7704
7705            if (!Intent.isAccessUriMode(modeFlags)) {
7706                return;
7707            }
7708
7709            final String authority = uri.getAuthority();
7710            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7711            if (pi == null) {
7712                Slog.w(TAG, "No content provider found for permission revoke: "
7713                        + uri.toSafeString());
7714                return;
7715            }
7716
7717            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7718        }
7719    }
7720
7721    /**
7722     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7723     * given package.
7724     *
7725     * @param packageName Package name to match, or {@code null} to apply to all
7726     *            packages.
7727     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7728     *            to all users.
7729     * @param persistable If persistable grants should be removed.
7730     */
7731    private void removeUriPermissionsForPackageLocked(
7732            String packageName, int userHandle, boolean persistable) {
7733        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7734            throw new IllegalArgumentException("Must narrow by either package or user");
7735        }
7736
7737        boolean persistChanged = false;
7738
7739        int N = mGrantedUriPermissions.size();
7740        for (int i = 0; i < N; i++) {
7741            final int targetUid = mGrantedUriPermissions.keyAt(i);
7742            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7743
7744            // Only inspect grants matching user
7745            if (userHandle == UserHandle.USER_ALL
7746                    || userHandle == UserHandle.getUserId(targetUid)) {
7747                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7748                    final UriPermission perm = it.next();
7749
7750                    // Only inspect grants matching package
7751                    if (packageName == null || perm.sourcePkg.equals(packageName)
7752                            || perm.targetPkg.equals(packageName)) {
7753                        persistChanged |= perm.revokeModes(persistable
7754                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7755
7756                        // Only remove when no modes remain; any persisted grants
7757                        // will keep this alive.
7758                        if (perm.modeFlags == 0) {
7759                            it.remove();
7760                        }
7761                    }
7762                }
7763
7764                if (perms.isEmpty()) {
7765                    mGrantedUriPermissions.remove(targetUid);
7766                    N--;
7767                    i--;
7768                }
7769            }
7770        }
7771
7772        if (persistChanged) {
7773            schedulePersistUriGrants();
7774        }
7775    }
7776
7777    @Override
7778    public IBinder newUriPermissionOwner(String name) {
7779        enforceNotIsolatedCaller("newUriPermissionOwner");
7780        synchronized(this) {
7781            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7782            return owner.getExternalTokenLocked();
7783        }
7784    }
7785
7786    /**
7787     * @param uri This uri must NOT contain an embedded userId.
7788     * @param sourceUserId The userId in which the uri is to be resolved.
7789     * @param targetUserId The userId of the app that receives the grant.
7790     */
7791    @Override
7792    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7793            final int modeFlags, int sourceUserId, int targetUserId) {
7794        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7795                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7796        synchronized(this) {
7797            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7798            if (owner == null) {
7799                throw new IllegalArgumentException("Unknown owner: " + token);
7800            }
7801            if (fromUid != Binder.getCallingUid()) {
7802                if (Binder.getCallingUid() != Process.myUid()) {
7803                    // Only system code can grant URI permissions on behalf
7804                    // of other users.
7805                    throw new SecurityException("nice try");
7806                }
7807            }
7808            if (targetPkg == null) {
7809                throw new IllegalArgumentException("null target");
7810            }
7811            if (uri == null) {
7812                throw new IllegalArgumentException("null uri");
7813            }
7814
7815            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7816                    modeFlags, owner, targetUserId);
7817        }
7818    }
7819
7820    /**
7821     * @param uri This uri must NOT contain an embedded userId.
7822     * @param userId The userId in which the uri is to be resolved.
7823     */
7824    @Override
7825    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7826        synchronized(this) {
7827            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7828            if (owner == null) {
7829                throw new IllegalArgumentException("Unknown owner: " + token);
7830            }
7831
7832            if (uri == null) {
7833                owner.removeUriPermissionsLocked(mode);
7834            } else {
7835                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7836            }
7837        }
7838    }
7839
7840    private void schedulePersistUriGrants() {
7841        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7842            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7843                    10 * DateUtils.SECOND_IN_MILLIS);
7844        }
7845    }
7846
7847    private void writeGrantedUriPermissions() {
7848        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7849
7850        // Snapshot permissions so we can persist without lock
7851        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7852        synchronized (this) {
7853            final int size = mGrantedUriPermissions.size();
7854            for (int i = 0; i < size; i++) {
7855                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7856                for (UriPermission perm : perms.values()) {
7857                    if (perm.persistedModeFlags != 0) {
7858                        persist.add(perm.snapshot());
7859                    }
7860                }
7861            }
7862        }
7863
7864        FileOutputStream fos = null;
7865        try {
7866            fos = mGrantFile.startWrite();
7867
7868            XmlSerializer out = new FastXmlSerializer();
7869            out.setOutput(fos, StandardCharsets.UTF_8.name());
7870            out.startDocument(null, true);
7871            out.startTag(null, TAG_URI_GRANTS);
7872            for (UriPermission.Snapshot perm : persist) {
7873                out.startTag(null, TAG_URI_GRANT);
7874                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7875                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7876                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7877                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7878                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7879                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7880                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7881                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7882                out.endTag(null, TAG_URI_GRANT);
7883            }
7884            out.endTag(null, TAG_URI_GRANTS);
7885            out.endDocument();
7886
7887            mGrantFile.finishWrite(fos);
7888        } catch (IOException e) {
7889            if (fos != null) {
7890                mGrantFile.failWrite(fos);
7891            }
7892        }
7893    }
7894
7895    private void readGrantedUriPermissionsLocked() {
7896        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7897
7898        final long now = System.currentTimeMillis();
7899
7900        FileInputStream fis = null;
7901        try {
7902            fis = mGrantFile.openRead();
7903            final XmlPullParser in = Xml.newPullParser();
7904            in.setInput(fis, StandardCharsets.UTF_8.name());
7905
7906            int type;
7907            while ((type = in.next()) != END_DOCUMENT) {
7908                final String tag = in.getName();
7909                if (type == START_TAG) {
7910                    if (TAG_URI_GRANT.equals(tag)) {
7911                        final int sourceUserId;
7912                        final int targetUserId;
7913                        final int userHandle = readIntAttribute(in,
7914                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7915                        if (userHandle != UserHandle.USER_NULL) {
7916                            // For backwards compatibility.
7917                            sourceUserId = userHandle;
7918                            targetUserId = userHandle;
7919                        } else {
7920                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7921                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7922                        }
7923                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7924                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7925                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7926                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7927                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7928                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7929
7930                        // Sanity check that provider still belongs to source package
7931                        final ProviderInfo pi = getProviderInfoLocked(
7932                                uri.getAuthority(), sourceUserId);
7933                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7934                            int targetUid = -1;
7935                            try {
7936                                targetUid = AppGlobals.getPackageManager()
7937                                        .getPackageUid(targetPkg, targetUserId);
7938                            } catch (RemoteException e) {
7939                            }
7940                            if (targetUid != -1) {
7941                                final UriPermission perm = findOrCreateUriPermissionLocked(
7942                                        sourcePkg, targetPkg, targetUid,
7943                                        new GrantUri(sourceUserId, uri, prefix));
7944                                perm.initPersistedModes(modeFlags, createdTime);
7945                            }
7946                        } else {
7947                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7948                                    + " but instead found " + pi);
7949                        }
7950                    }
7951                }
7952            }
7953        } catch (FileNotFoundException e) {
7954            // Missing grants is okay
7955        } catch (IOException e) {
7956            Slog.wtf(TAG, "Failed reading Uri grants", e);
7957        } catch (XmlPullParserException e) {
7958            Slog.wtf(TAG, "Failed reading Uri grants", e);
7959        } finally {
7960            IoUtils.closeQuietly(fis);
7961        }
7962    }
7963
7964    /**
7965     * @param uri This uri must NOT contain an embedded userId.
7966     * @param userId The userId in which the uri is to be resolved.
7967     */
7968    @Override
7969    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7970        enforceNotIsolatedCaller("takePersistableUriPermission");
7971
7972        Preconditions.checkFlagsArgument(modeFlags,
7973                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7974
7975        synchronized (this) {
7976            final int callingUid = Binder.getCallingUid();
7977            boolean persistChanged = false;
7978            GrantUri grantUri = new GrantUri(userId, uri, false);
7979
7980            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7981                    new GrantUri(userId, uri, false));
7982            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7983                    new GrantUri(userId, uri, true));
7984
7985            final boolean exactValid = (exactPerm != null)
7986                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7987            final boolean prefixValid = (prefixPerm != null)
7988                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7989
7990            if (!(exactValid || prefixValid)) {
7991                throw new SecurityException("No persistable permission grants found for UID "
7992                        + callingUid + " and Uri " + grantUri.toSafeString());
7993            }
7994
7995            if (exactValid) {
7996                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7997            }
7998            if (prefixValid) {
7999                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8000            }
8001
8002            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8003
8004            if (persistChanged) {
8005                schedulePersistUriGrants();
8006            }
8007        }
8008    }
8009
8010    /**
8011     * @param uri This uri must NOT contain an embedded userId.
8012     * @param userId The userId in which the uri is to be resolved.
8013     */
8014    @Override
8015    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8016        enforceNotIsolatedCaller("releasePersistableUriPermission");
8017
8018        Preconditions.checkFlagsArgument(modeFlags,
8019                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8020
8021        synchronized (this) {
8022            final int callingUid = Binder.getCallingUid();
8023            boolean persistChanged = false;
8024
8025            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8026                    new GrantUri(userId, uri, false));
8027            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8028                    new GrantUri(userId, uri, true));
8029            if (exactPerm == null && prefixPerm == null) {
8030                throw new SecurityException("No permission grants found for UID " + callingUid
8031                        + " and Uri " + uri.toSafeString());
8032            }
8033
8034            if (exactPerm != null) {
8035                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8036                removeUriPermissionIfNeededLocked(exactPerm);
8037            }
8038            if (prefixPerm != null) {
8039                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8040                removeUriPermissionIfNeededLocked(prefixPerm);
8041            }
8042
8043            if (persistChanged) {
8044                schedulePersistUriGrants();
8045            }
8046        }
8047    }
8048
8049    /**
8050     * Prune any older {@link UriPermission} for the given UID until outstanding
8051     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8052     *
8053     * @return if any mutations occured that require persisting.
8054     */
8055    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8056        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8057        if (perms == null) return false;
8058        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8059
8060        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8061        for (UriPermission perm : perms.values()) {
8062            if (perm.persistedModeFlags != 0) {
8063                persisted.add(perm);
8064            }
8065        }
8066
8067        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8068        if (trimCount <= 0) return false;
8069
8070        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8071        for (int i = 0; i < trimCount; i++) {
8072            final UriPermission perm = persisted.get(i);
8073
8074            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8075                    "Trimming grant created at " + perm.persistedCreateTime);
8076
8077            perm.releasePersistableModes(~0);
8078            removeUriPermissionIfNeededLocked(perm);
8079        }
8080
8081        return true;
8082    }
8083
8084    @Override
8085    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8086            String packageName, boolean incoming) {
8087        enforceNotIsolatedCaller("getPersistedUriPermissions");
8088        Preconditions.checkNotNull(packageName, "packageName");
8089
8090        final int callingUid = Binder.getCallingUid();
8091        final IPackageManager pm = AppGlobals.getPackageManager();
8092        try {
8093            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8094            if (packageUid != callingUid) {
8095                throw new SecurityException(
8096                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8097            }
8098        } catch (RemoteException e) {
8099            throw new SecurityException("Failed to verify package name ownership");
8100        }
8101
8102        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8103        synchronized (this) {
8104            if (incoming) {
8105                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8106                        callingUid);
8107                if (perms == null) {
8108                    Slog.w(TAG, "No permission grants found for " + packageName);
8109                } else {
8110                    for (UriPermission perm : perms.values()) {
8111                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8112                            result.add(perm.buildPersistedPublicApiObject());
8113                        }
8114                    }
8115                }
8116            } else {
8117                final int size = mGrantedUriPermissions.size();
8118                for (int i = 0; i < size; i++) {
8119                    final ArrayMap<GrantUri, UriPermission> perms =
8120                            mGrantedUriPermissions.valueAt(i);
8121                    for (UriPermission perm : perms.values()) {
8122                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8123                            result.add(perm.buildPersistedPublicApiObject());
8124                        }
8125                    }
8126                }
8127            }
8128        }
8129        return new ParceledListSlice<android.content.UriPermission>(result);
8130    }
8131
8132    @Override
8133    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8134        synchronized (this) {
8135            ProcessRecord app =
8136                who != null ? getRecordForAppLocked(who) : null;
8137            if (app == null) return;
8138
8139            Message msg = Message.obtain();
8140            msg.what = WAIT_FOR_DEBUGGER_MSG;
8141            msg.obj = app;
8142            msg.arg1 = waiting ? 1 : 0;
8143            mUiHandler.sendMessage(msg);
8144        }
8145    }
8146
8147    @Override
8148    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8149        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8150        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8151        outInfo.availMem = Process.getFreeMemory();
8152        outInfo.totalMem = Process.getTotalMemory();
8153        outInfo.threshold = homeAppMem;
8154        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8155        outInfo.hiddenAppThreshold = cachedAppMem;
8156        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8157                ProcessList.SERVICE_ADJ);
8158        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8159                ProcessList.VISIBLE_APP_ADJ);
8160        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8161                ProcessList.FOREGROUND_APP_ADJ);
8162    }
8163
8164    // =========================================================
8165    // TASK MANAGEMENT
8166    // =========================================================
8167
8168    @Override
8169    public List<IAppTask> getAppTasks(String callingPackage) {
8170        int callingUid = Binder.getCallingUid();
8171        long ident = Binder.clearCallingIdentity();
8172
8173        synchronized(this) {
8174            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8175            try {
8176                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8177
8178                final int N = mRecentTasks.size();
8179                for (int i = 0; i < N; i++) {
8180                    TaskRecord tr = mRecentTasks.get(i);
8181                    // Skip tasks that do not match the caller.  We don't need to verify
8182                    // callingPackage, because we are also limiting to callingUid and know
8183                    // that will limit to the correct security sandbox.
8184                    if (tr.effectiveUid != callingUid) {
8185                        continue;
8186                    }
8187                    Intent intent = tr.getBaseIntent();
8188                    if (intent == null ||
8189                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8190                        continue;
8191                    }
8192                    ActivityManager.RecentTaskInfo taskInfo =
8193                            createRecentTaskInfoFromTaskRecord(tr);
8194                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8195                    list.add(taskImpl);
8196                }
8197            } finally {
8198                Binder.restoreCallingIdentity(ident);
8199            }
8200            return list;
8201        }
8202    }
8203
8204    @Override
8205    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8206        final int callingUid = Binder.getCallingUid();
8207        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8208
8209        synchronized(this) {
8210            if (DEBUG_ALL) Slog.v(
8211                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8212
8213            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8214                    callingUid);
8215
8216            // TODO: Improve with MRU list from all ActivityStacks.
8217            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8218        }
8219
8220        return list;
8221    }
8222
8223    /**
8224     * Creates a new RecentTaskInfo from a TaskRecord.
8225     */
8226    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8227        // Update the task description to reflect any changes in the task stack
8228        tr.updateTaskDescription();
8229
8230        // Compose the recent task info
8231        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8232        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8233        rti.persistentId = tr.taskId;
8234        rti.baseIntent = new Intent(tr.getBaseIntent());
8235        rti.origActivity = tr.origActivity;
8236        rti.description = tr.lastDescription;
8237        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8238        rti.userId = tr.userId;
8239        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8240        rti.firstActiveTime = tr.firstActiveTime;
8241        rti.lastActiveTime = tr.lastActiveTime;
8242        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8243        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8244        rti.numActivities = 0;
8245
8246        ActivityRecord base = null;
8247        ActivityRecord top = null;
8248        ActivityRecord tmp;
8249
8250        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8251            tmp = tr.mActivities.get(i);
8252            if (tmp.finishing) {
8253                continue;
8254            }
8255            base = tmp;
8256            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8257                top = base;
8258            }
8259            rti.numActivities++;
8260        }
8261
8262        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8263        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8264
8265        return rti;
8266    }
8267
8268    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8269        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8270                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8271        if (!allowed) {
8272            if (checkPermission(android.Manifest.permission.GET_TASKS,
8273                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8274                // Temporary compatibility: some existing apps on the system image may
8275                // still be requesting the old permission and not switched to the new
8276                // one; if so, we'll still allow them full access.  This means we need
8277                // to see if they are holding the old permission and are a system app.
8278                try {
8279                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8280                        allowed = true;
8281                        Slog.w(TAG, caller + ": caller " + callingUid
8282                                + " is using old GET_TASKS but privileged; allowing");
8283                    }
8284                } catch (RemoteException e) {
8285                }
8286            }
8287        }
8288        if (!allowed) {
8289            Slog.w(TAG, caller + ": caller " + callingUid
8290                    + " does not hold REAL_GET_TASKS; limiting output");
8291        }
8292        return allowed;
8293    }
8294
8295    @Override
8296    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8297        final int callingUid = Binder.getCallingUid();
8298        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8299                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8300
8301        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8302        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8303        synchronized (this) {
8304            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8305                    callingUid);
8306            final boolean detailed = checkCallingPermission(
8307                    android.Manifest.permission.GET_DETAILED_TASKS)
8308                    == PackageManager.PERMISSION_GRANTED;
8309
8310            final int recentsCount = mRecentTasks.size();
8311            ArrayList<ActivityManager.RecentTaskInfo> res =
8312                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8313
8314            final Set<Integer> includedUsers;
8315            if (includeProfiles) {
8316                includedUsers = getProfileIdsLocked(userId);
8317            } else {
8318                includedUsers = new HashSet<>();
8319            }
8320            includedUsers.add(Integer.valueOf(userId));
8321
8322            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8323                TaskRecord tr = mRecentTasks.get(i);
8324                // Only add calling user or related users recent tasks
8325                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8326                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8327                    continue;
8328                }
8329
8330                // Return the entry if desired by the caller.  We always return
8331                // the first entry, because callers always expect this to be the
8332                // foreground app.  We may filter others if the caller has
8333                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8334                // we should exclude the entry.
8335
8336                if (i == 0
8337                        || withExcluded
8338                        || (tr.intent == null)
8339                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8340                                == 0)) {
8341                    if (!allowed) {
8342                        // If the caller doesn't have the GET_TASKS permission, then only
8343                        // allow them to see a small subset of tasks -- their own and home.
8344                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8345                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8346                            continue;
8347                        }
8348                    }
8349                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8350                        if (tr.stack != null && tr.stack.isHomeStack()) {
8351                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8352                                    "Skipping, home stack task: " + tr);
8353                            continue;
8354                        }
8355                    }
8356                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8357                        // Don't include auto remove tasks that are finished or finishing.
8358                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8359                                "Skipping, auto-remove without activity: " + tr);
8360                        continue;
8361                    }
8362                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8363                            && !tr.isAvailable) {
8364                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8365                                "Skipping, unavail real act: " + tr);
8366                        continue;
8367                    }
8368
8369                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8370                    if (!detailed) {
8371                        rti.baseIntent.replaceExtras((Bundle)null);
8372                    }
8373
8374                    res.add(rti);
8375                    maxNum--;
8376                }
8377            }
8378            return res;
8379        }
8380    }
8381
8382    @Override
8383    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8384        synchronized (this) {
8385            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8386                    "getTaskThumbnail()");
8387            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8388            if (tr != null) {
8389                return tr.getTaskThumbnailLocked();
8390            }
8391        }
8392        return null;
8393    }
8394
8395    @Override
8396    public int addAppTask(IBinder activityToken, Intent intent,
8397            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8398        final int callingUid = Binder.getCallingUid();
8399        final long callingIdent = Binder.clearCallingIdentity();
8400
8401        try {
8402            synchronized (this) {
8403                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8404                if (r == null) {
8405                    throw new IllegalArgumentException("Activity does not exist; token="
8406                            + activityToken);
8407                }
8408                ComponentName comp = intent.getComponent();
8409                if (comp == null) {
8410                    throw new IllegalArgumentException("Intent " + intent
8411                            + " must specify explicit component");
8412                }
8413                if (thumbnail.getWidth() != mThumbnailWidth
8414                        || thumbnail.getHeight() != mThumbnailHeight) {
8415                    throw new IllegalArgumentException("Bad thumbnail size: got "
8416                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8417                            + mThumbnailWidth + "x" + mThumbnailHeight);
8418                }
8419                if (intent.getSelector() != null) {
8420                    intent.setSelector(null);
8421                }
8422                if (intent.getSourceBounds() != null) {
8423                    intent.setSourceBounds(null);
8424                }
8425                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8426                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8427                        // The caller has added this as an auto-remove task...  that makes no
8428                        // sense, so turn off auto-remove.
8429                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8430                    }
8431                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8432                    // Must be a new task.
8433                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8434                }
8435                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8436                    mLastAddedTaskActivity = null;
8437                }
8438                ActivityInfo ainfo = mLastAddedTaskActivity;
8439                if (ainfo == null) {
8440                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8441                            comp, 0, UserHandle.getUserId(callingUid));
8442                    if (ainfo.applicationInfo.uid != callingUid) {
8443                        throw new SecurityException(
8444                                "Can't add task for another application: target uid="
8445                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8446                    }
8447                }
8448
8449                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8450                        intent, description);
8451
8452                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8453                if (trimIdx >= 0) {
8454                    // If this would have caused a trim, then we'll abort because that
8455                    // means it would be added at the end of the list but then just removed.
8456                    return INVALID_TASK_ID;
8457                }
8458
8459                final int N = mRecentTasks.size();
8460                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8461                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8462                    tr.removedFromRecents();
8463                }
8464
8465                task.inRecents = true;
8466                mRecentTasks.add(task);
8467                r.task.stack.addTask(task, false, false);
8468
8469                task.setLastThumbnail(thumbnail);
8470                task.freeLastThumbnail();
8471
8472                return task.taskId;
8473            }
8474        } finally {
8475            Binder.restoreCallingIdentity(callingIdent);
8476        }
8477    }
8478
8479    @Override
8480    public Point getAppTaskThumbnailSize() {
8481        synchronized (this) {
8482            return new Point(mThumbnailWidth,  mThumbnailHeight);
8483        }
8484    }
8485
8486    @Override
8487    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8488        synchronized (this) {
8489            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8490            if (r != null) {
8491                r.setTaskDescription(td);
8492                r.task.updateTaskDescription();
8493            }
8494        }
8495    }
8496
8497    @Override
8498    public void setTaskResizeable(int taskId, boolean resizeable) {
8499        synchronized (this) {
8500            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8501            if (task == null) {
8502                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8503                return;
8504            }
8505            if (task.mResizeable != resizeable) {
8506                task.mResizeable = resizeable;
8507                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8508                mStackSupervisor.resumeTopActivitiesLocked();
8509            }
8510        }
8511    }
8512
8513    @Override
8514    public void resizeTask(int taskId, Rect bounds) {
8515        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8516                "resizeTask()");
8517        long ident = Binder.clearCallingIdentity();
8518        try {
8519            synchronized (this) {
8520                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8521                if (task == null) {
8522                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8523                    return;
8524                }
8525                mStackSupervisor.resizeTaskLocked(task, bounds);
8526            }
8527        } finally {
8528            Binder.restoreCallingIdentity(ident);
8529        }
8530    }
8531
8532    @Override
8533    public Bitmap getTaskDescriptionIcon(String filename) {
8534        if (!FileUtils.isValidExtFilename(filename)
8535                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8536            throw new IllegalArgumentException("Bad filename: " + filename);
8537        }
8538        return mTaskPersister.getTaskDescriptionIcon(filename);
8539    }
8540
8541    @Override
8542    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8543            throws RemoteException {
8544        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8545                opts.getCustomInPlaceResId() == 0) {
8546            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8547                    "with valid animation");
8548        }
8549        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8550        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8551                opts.getCustomInPlaceResId());
8552        mWindowManager.executeAppTransition();
8553    }
8554
8555    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8556        mRecentTasks.remove(tr);
8557        tr.removedFromRecents();
8558        ComponentName component = tr.getBaseIntent().getComponent();
8559        if (component == null) {
8560            Slog.w(TAG, "No component for base intent of task: " + tr);
8561            return;
8562        }
8563
8564        // Find any running services associated with this app and stop if needed.
8565        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8566
8567        if (!killProcess) {
8568            return;
8569        }
8570
8571        // Determine if the process(es) for this task should be killed.
8572        final String pkg = component.getPackageName();
8573        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8574        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8575        for (int i = 0; i < pmap.size(); i++) {
8576
8577            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8578            for (int j = 0; j < uids.size(); j++) {
8579                ProcessRecord proc = uids.valueAt(j);
8580                if (proc.userId != tr.userId) {
8581                    // Don't kill process for a different user.
8582                    continue;
8583                }
8584                if (proc == mHomeProcess) {
8585                    // Don't kill the home process along with tasks from the same package.
8586                    continue;
8587                }
8588                if (!proc.pkgList.containsKey(pkg)) {
8589                    // Don't kill process that is not associated with this task.
8590                    continue;
8591                }
8592
8593                for (int k = 0; k < proc.activities.size(); k++) {
8594                    TaskRecord otherTask = proc.activities.get(k).task;
8595                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8596                        // Don't kill process(es) that has an activity in a different task that is
8597                        // also in recents.
8598                        return;
8599                    }
8600                }
8601
8602                if (proc.foregroundServices) {
8603                    // Don't kill process(es) with foreground service.
8604                    return;
8605                }
8606
8607                // Add process to kill list.
8608                procsToKill.add(proc);
8609            }
8610        }
8611
8612        // Kill the running processes.
8613        for (int i = 0; i < procsToKill.size(); i++) {
8614            ProcessRecord pr = procsToKill.get(i);
8615            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8616                    && pr.curReceiver == null) {
8617                pr.kill("remove task", true);
8618            } else {
8619                // We delay killing processes that are not in the background or running a receiver.
8620                pr.waitingToKill = "remove task";
8621            }
8622        }
8623    }
8624
8625    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8626        // Remove all tasks with activities in the specified package from the list of recent tasks
8627        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8628            TaskRecord tr = mRecentTasks.get(i);
8629            if (tr.userId != userId) continue;
8630
8631            ComponentName cn = tr.intent.getComponent();
8632            if (cn != null && cn.getPackageName().equals(packageName)) {
8633                // If the package name matches, remove the task.
8634                removeTaskByIdLocked(tr.taskId, true);
8635            }
8636        }
8637    }
8638
8639    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8640            int userId) {
8641
8642        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8643            TaskRecord tr = mRecentTasks.get(i);
8644            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8645                continue;
8646            }
8647
8648            ComponentName cn = tr.intent.getComponent();
8649            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8650                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8651            if (sameComponent) {
8652                removeTaskByIdLocked(tr.taskId, false);
8653            }
8654        }
8655    }
8656
8657    /**
8658     * Removes the task with the specified task id.
8659     *
8660     * @param taskId Identifier of the task to be removed.
8661     * @param killProcess Kill any process associated with the task if possible.
8662     * @return Returns true if the given task was found and removed.
8663     */
8664    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8665        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8666        if (tr != null) {
8667            tr.removeTaskActivitiesLocked();
8668            cleanUpRemovedTaskLocked(tr, killProcess);
8669            if (tr.isPersistable) {
8670                notifyTaskPersisterLocked(null, true);
8671            }
8672            return true;
8673        }
8674        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8675        return false;
8676    }
8677
8678    @Override
8679    public boolean removeTask(int taskId) {
8680        synchronized (this) {
8681            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8682                    "removeTask()");
8683            long ident = Binder.clearCallingIdentity();
8684            try {
8685                return removeTaskByIdLocked(taskId, true);
8686            } finally {
8687                Binder.restoreCallingIdentity(ident);
8688            }
8689        }
8690    }
8691
8692    /**
8693     * TODO: Add mController hook
8694     */
8695    @Override
8696    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8697        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8698
8699        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8700        synchronized(this) {
8701            moveTaskToFrontLocked(taskId, flags, options);
8702        }
8703    }
8704
8705    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8706        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8707                Binder.getCallingUid(), -1, -1, "Task to front")) {
8708            ActivityOptions.abort(options);
8709            return;
8710        }
8711        final long origId = Binder.clearCallingIdentity();
8712        try {
8713            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8714            if (task == null) {
8715                Slog.d(TAG, "Could not find task for id: "+ taskId);
8716                return;
8717            }
8718            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8719                mStackSupervisor.showLockTaskToast();
8720                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8721                return;
8722            }
8723            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8724            if (prev != null && prev.isRecentsActivity()) {
8725                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8726            }
8727            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8728        } finally {
8729            Binder.restoreCallingIdentity(origId);
8730        }
8731        ActivityOptions.abort(options);
8732    }
8733
8734    /**
8735     * Moves an activity, and all of the other activities within the same task, to the bottom
8736     * of the history stack.  The activity's order within the task is unchanged.
8737     *
8738     * @param token A reference to the activity we wish to move
8739     * @param nonRoot If false then this only works if the activity is the root
8740     *                of a task; if true it will work for any activity in a task.
8741     * @return Returns true if the move completed, false if not.
8742     */
8743    @Override
8744    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8745        enforceNotIsolatedCaller("moveActivityTaskToBack");
8746        synchronized(this) {
8747            final long origId = Binder.clearCallingIdentity();
8748            try {
8749                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8750                final TaskRecord task = mRecentTasks.taskForIdLocked(taskId);
8751                if (task != null) {
8752                    if (mStackSupervisor.isLockedTask(task)) {
8753                        mStackSupervisor.showLockTaskToast();
8754                        return false;
8755                    }
8756                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8757                }
8758            } finally {
8759                Binder.restoreCallingIdentity(origId);
8760            }
8761        }
8762        return false;
8763    }
8764
8765    @Override
8766    public void moveTaskBackwards(int task) {
8767        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8768                "moveTaskBackwards()");
8769
8770        synchronized(this) {
8771            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8772                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8773                return;
8774            }
8775            final long origId = Binder.clearCallingIdentity();
8776            moveTaskBackwardsLocked(task);
8777            Binder.restoreCallingIdentity(origId);
8778        }
8779    }
8780
8781    private final void moveTaskBackwardsLocked(int task) {
8782        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8783    }
8784
8785    @Override
8786    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8787            IActivityContainerCallback callback) throws RemoteException {
8788        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8789                "createActivityContainer()");
8790        synchronized (this) {
8791            if (parentActivityToken == null) {
8792                throw new IllegalArgumentException("parent token must not be null");
8793            }
8794            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8795            if (r == null) {
8796                return null;
8797            }
8798            if (callback == null) {
8799                throw new IllegalArgumentException("callback must not be null");
8800            }
8801            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8802        }
8803    }
8804
8805    @Override
8806    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8807        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8808                "deleteActivityContainer()");
8809        synchronized (this) {
8810            mStackSupervisor.deleteActivityContainer(container);
8811        }
8812    }
8813
8814    @Override
8815    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8816        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8817                "createStackOnDisplay()");
8818        synchronized (this) {
8819            final int stackId = mStackSupervisor.getNextStackId();
8820            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8821            if (stack == null) {
8822                return null;
8823            }
8824            return stack.mActivityContainer;
8825        }
8826    }
8827
8828    @Override
8829    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8830        synchronized (this) {
8831            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8832            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8833                return stack.mActivityContainer.getDisplayId();
8834            }
8835            return Display.DEFAULT_DISPLAY;
8836        }
8837    }
8838
8839    @Override
8840    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8841        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8842                "moveTaskToStack()");
8843        if (stackId == HOME_STACK_ID) {
8844            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8845                    new RuntimeException("here").fillInStackTrace());
8846        }
8847        synchronized (this) {
8848            long ident = Binder.clearCallingIdentity();
8849            try {
8850                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8851                        + " to stackId=" + stackId + " toTop=" + toTop);
8852                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8853            } finally {
8854                Binder.restoreCallingIdentity(ident);
8855            }
8856        }
8857    }
8858
8859    @Override
8860    public void resizeStack(int stackId, Rect bounds) {
8861        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8862                "resizeStack()");
8863        long ident = Binder.clearCallingIdentity();
8864        try {
8865            synchronized (this) {
8866                mStackSupervisor.resizeStackLocked(stackId, bounds);
8867            }
8868        } finally {
8869            Binder.restoreCallingIdentity(ident);
8870        }
8871    }
8872
8873    @Override
8874    public List<StackInfo> getAllStackInfos() {
8875        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8876                "getAllStackInfos()");
8877        long ident = Binder.clearCallingIdentity();
8878        try {
8879            synchronized (this) {
8880                return mStackSupervisor.getAllStackInfosLocked();
8881            }
8882        } finally {
8883            Binder.restoreCallingIdentity(ident);
8884        }
8885    }
8886
8887    @Override
8888    public StackInfo getStackInfo(int stackId) {
8889        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8890                "getStackInfo()");
8891        long ident = Binder.clearCallingIdentity();
8892        try {
8893            synchronized (this) {
8894                return mStackSupervisor.getStackInfoLocked(stackId);
8895            }
8896        } finally {
8897            Binder.restoreCallingIdentity(ident);
8898        }
8899    }
8900
8901    @Override
8902    public boolean isInHomeStack(int taskId) {
8903        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8904                "getStackInfo()");
8905        long ident = Binder.clearCallingIdentity();
8906        try {
8907            synchronized (this) {
8908                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8909                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8910            }
8911        } finally {
8912            Binder.restoreCallingIdentity(ident);
8913        }
8914    }
8915
8916    @Override
8917    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8918        synchronized(this) {
8919            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8920        }
8921    }
8922
8923    @Override
8924    public void updateDeviceOwner(String packageName) {
8925        final int callingUid = Binder.getCallingUid();
8926        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8927            throw new SecurityException("updateDeviceOwner called from non-system process");
8928        }
8929        synchronized (this) {
8930            mDeviceOwnerName = packageName;
8931        }
8932    }
8933
8934    @Override
8935    public void updateLockTaskPackages(int userId, String[] packages) {
8936        final int callingUid = Binder.getCallingUid();
8937        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8938            throw new SecurityException("updateLockTaskPackage called from non-system process");
8939        }
8940        synchronized (this) {
8941            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
8942                    Arrays.toString(packages));
8943            mLockTaskPackages.put(userId, packages);
8944            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
8945        }
8946    }
8947
8948
8949    void startLockTaskModeLocked(TaskRecord task) {
8950        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
8951        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
8952            return;
8953        }
8954
8955        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
8956        // is initiated by system after the pinning request was shown and locked mode is initiated
8957        // by an authorized app directly
8958        final int callingUid = Binder.getCallingUid();
8959        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
8960        long ident = Binder.clearCallingIdentity();
8961        try {
8962            final ActivityStack stack = mStackSupervisor.getFocusedStack();
8963            if (!isSystemInitiated) {
8964                task.mLockTaskUid = callingUid;
8965                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
8966                    // startLockTask() called by app and task mode is lockTaskModeDefault.
8967                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
8968                    StatusBarManagerInternal statusBarManager =
8969                            LocalServices.getService(StatusBarManagerInternal.class);
8970                    if (statusBarManager != null) {
8971                        statusBarManager.showScreenPinningRequest();
8972                    }
8973                    return;
8974                }
8975
8976                if (stack == null || task != stack.topTask()) {
8977                    throw new IllegalArgumentException("Invalid task, not in foreground");
8978                }
8979            }
8980            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
8981                    "Locking fully");
8982            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
8983                    ActivityManager.LOCK_TASK_MODE_PINNED :
8984                    ActivityManager.LOCK_TASK_MODE_LOCKED,
8985                    "startLockTask", true);
8986        } finally {
8987            Binder.restoreCallingIdentity(ident);
8988        }
8989    }
8990
8991    @Override
8992    public void startLockTaskMode(int taskId) {
8993        synchronized (this) {
8994            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8995            if (task != null) {
8996                startLockTaskModeLocked(task);
8997            }
8998        }
8999    }
9000
9001    @Override
9002    public void startLockTaskMode(IBinder token) {
9003        synchronized (this) {
9004            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9005            if (r == null) {
9006                return;
9007            }
9008            final TaskRecord task = r.task;
9009            if (task != null) {
9010                startLockTaskModeLocked(task);
9011            }
9012        }
9013    }
9014
9015    @Override
9016    public void startLockTaskModeOnCurrent() throws RemoteException {
9017        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9018                "startLockTaskModeOnCurrent");
9019        long ident = Binder.clearCallingIdentity();
9020        try {
9021            synchronized (this) {
9022                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9023                if (r != null) {
9024                    startLockTaskModeLocked(r.task);
9025                }
9026            }
9027        } finally {
9028            Binder.restoreCallingIdentity(ident);
9029        }
9030    }
9031
9032    @Override
9033    public void stopLockTaskMode() {
9034        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9035        if (lockTask == null) {
9036            // Our work here is done.
9037            return;
9038        }
9039
9040        final int callingUid = Binder.getCallingUid();
9041        final int lockTaskUid = lockTask.mLockTaskUid;
9042        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9043        // It is possible lockTaskMode was started by the system process because
9044        // android:lockTaskMode is set to a locking value in the application manifest instead of
9045        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9046        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9047        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9048                callingUid != lockTaskUid
9049                && (lockTaskUid != 0
9050                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9051            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9052                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9053        }
9054
9055        long ident = Binder.clearCallingIdentity();
9056        try {
9057            Log.d(TAG, "stopLockTaskMode");
9058            // Stop lock task
9059            synchronized (this) {
9060                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9061                        "stopLockTask", true);
9062            }
9063        } finally {
9064            Binder.restoreCallingIdentity(ident);
9065        }
9066    }
9067
9068    @Override
9069    public void stopLockTaskModeOnCurrent() throws RemoteException {
9070        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9071                "stopLockTaskModeOnCurrent");
9072        long ident = Binder.clearCallingIdentity();
9073        try {
9074            stopLockTaskMode();
9075        } finally {
9076            Binder.restoreCallingIdentity(ident);
9077        }
9078    }
9079
9080    @Override
9081    public boolean isInLockTaskMode() {
9082        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9083    }
9084
9085    @Override
9086    public int getLockTaskModeState() {
9087        synchronized (this) {
9088            return mStackSupervisor.getLockTaskModeState();
9089        }
9090    }
9091
9092    @Override
9093    public void showLockTaskEscapeMessage(IBinder token) {
9094        synchronized (this) {
9095            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9096            if (r == null) {
9097                return;
9098            }
9099            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9100        }
9101    }
9102
9103    // =========================================================
9104    // CONTENT PROVIDERS
9105    // =========================================================
9106
9107    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9108        List<ProviderInfo> providers = null;
9109        try {
9110            providers = AppGlobals.getPackageManager().
9111                queryContentProviders(app.processName, app.uid,
9112                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9113        } catch (RemoteException ex) {
9114        }
9115        if (DEBUG_MU) Slog.v(TAG_MU,
9116                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9117        int userId = app.userId;
9118        if (providers != null) {
9119            int N = providers.size();
9120            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9121            for (int i=0; i<N; i++) {
9122                ProviderInfo cpi =
9123                    (ProviderInfo)providers.get(i);
9124                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9125                        cpi.name, cpi.flags);
9126                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9127                    // This is a singleton provider, but a user besides the
9128                    // default user is asking to initialize a process it runs
9129                    // in...  well, no, it doesn't actually run in this process,
9130                    // it runs in the process of the default user.  Get rid of it.
9131                    providers.remove(i);
9132                    N--;
9133                    i--;
9134                    continue;
9135                }
9136
9137                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9138                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9139                if (cpr == null) {
9140                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9141                    mProviderMap.putProviderByClass(comp, cpr);
9142                }
9143                if (DEBUG_MU) Slog.v(TAG_MU,
9144                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9145                app.pubProviders.put(cpi.name, cpr);
9146                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9147                    // Don't add this if it is a platform component that is marked
9148                    // to run in multiple processes, because this is actually
9149                    // part of the framework so doesn't make sense to track as a
9150                    // separate apk in the process.
9151                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9152                            mProcessStats);
9153                }
9154                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9155            }
9156        }
9157        return providers;
9158    }
9159
9160    /**
9161     * Check if {@link ProcessRecord} has a possible chance at accessing the
9162     * given {@link ProviderInfo}. Final permission checking is always done
9163     * in {@link ContentProvider}.
9164     */
9165    private final String checkContentProviderPermissionLocked(
9166            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9167        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9168        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9169        boolean checkedGrants = false;
9170        if (checkUser) {
9171            // Looking for cross-user grants before enforcing the typical cross-users permissions
9172            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9173            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9174                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9175                    return null;
9176                }
9177                checkedGrants = true;
9178            }
9179            userId = handleIncomingUser(callingPid, callingUid, userId,
9180                    false, ALLOW_NON_FULL,
9181                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9182            if (userId != tmpTargetUserId) {
9183                // When we actually went to determine the final targer user ID, this ended
9184                // up different than our initial check for the authority.  This is because
9185                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9186                // SELF.  So we need to re-check the grants again.
9187                checkedGrants = false;
9188            }
9189        }
9190        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9191                cpi.applicationInfo.uid, cpi.exported)
9192                == PackageManager.PERMISSION_GRANTED) {
9193            return null;
9194        }
9195        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9196                cpi.applicationInfo.uid, cpi.exported)
9197                == PackageManager.PERMISSION_GRANTED) {
9198            return null;
9199        }
9200
9201        PathPermission[] pps = cpi.pathPermissions;
9202        if (pps != null) {
9203            int i = pps.length;
9204            while (i > 0) {
9205                i--;
9206                PathPermission pp = pps[i];
9207                String pprperm = pp.getReadPermission();
9208                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9209                        cpi.applicationInfo.uid, cpi.exported)
9210                        == PackageManager.PERMISSION_GRANTED) {
9211                    return null;
9212                }
9213                String ppwperm = pp.getWritePermission();
9214                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9215                        cpi.applicationInfo.uid, cpi.exported)
9216                        == PackageManager.PERMISSION_GRANTED) {
9217                    return null;
9218                }
9219            }
9220        }
9221        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9222            return null;
9223        }
9224
9225        String msg;
9226        if (!cpi.exported) {
9227            msg = "Permission Denial: opening provider " + cpi.name
9228                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9229                    + ", uid=" + callingUid + ") that is not exported from uid "
9230                    + cpi.applicationInfo.uid;
9231        } else {
9232            msg = "Permission Denial: opening provider " + cpi.name
9233                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9234                    + ", uid=" + callingUid + ") requires "
9235                    + cpi.readPermission + " or " + cpi.writePermission;
9236        }
9237        Slog.w(TAG, msg);
9238        return msg;
9239    }
9240
9241    /**
9242     * Returns if the ContentProvider has granted a uri to callingUid
9243     */
9244    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9245        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9246        if (perms != null) {
9247            for (int i=perms.size()-1; i>=0; i--) {
9248                GrantUri grantUri = perms.keyAt(i);
9249                if (grantUri.sourceUserId == userId || !checkUser) {
9250                    if (matchesProvider(grantUri.uri, cpi)) {
9251                        return true;
9252                    }
9253                }
9254            }
9255        }
9256        return false;
9257    }
9258
9259    /**
9260     * Returns true if the uri authority is one of the authorities specified in the provider.
9261     */
9262    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9263        String uriAuth = uri.getAuthority();
9264        String cpiAuth = cpi.authority;
9265        if (cpiAuth.indexOf(';') == -1) {
9266            return cpiAuth.equals(uriAuth);
9267        }
9268        String[] cpiAuths = cpiAuth.split(";");
9269        int length = cpiAuths.length;
9270        for (int i = 0; i < length; i++) {
9271            if (cpiAuths[i].equals(uriAuth)) return true;
9272        }
9273        return false;
9274    }
9275
9276    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9277            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9278        if (r != null) {
9279            for (int i=0; i<r.conProviders.size(); i++) {
9280                ContentProviderConnection conn = r.conProviders.get(i);
9281                if (conn.provider == cpr) {
9282                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9283                            "Adding provider requested by "
9284                            + r.processName + " from process "
9285                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9286                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9287                    if (stable) {
9288                        conn.stableCount++;
9289                        conn.numStableIncs++;
9290                    } else {
9291                        conn.unstableCount++;
9292                        conn.numUnstableIncs++;
9293                    }
9294                    return conn;
9295                }
9296            }
9297            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9298            if (stable) {
9299                conn.stableCount = 1;
9300                conn.numStableIncs = 1;
9301            } else {
9302                conn.unstableCount = 1;
9303                conn.numUnstableIncs = 1;
9304            }
9305            cpr.connections.add(conn);
9306            r.conProviders.add(conn);
9307            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9308            return conn;
9309        }
9310        cpr.addExternalProcessHandleLocked(externalProcessToken);
9311        return null;
9312    }
9313
9314    boolean decProviderCountLocked(ContentProviderConnection conn,
9315            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9316        if (conn != null) {
9317            cpr = conn.provider;
9318            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9319                    "Removing provider requested by "
9320                    + conn.client.processName + " from process "
9321                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9322                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9323            if (stable) {
9324                conn.stableCount--;
9325            } else {
9326                conn.unstableCount--;
9327            }
9328            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9329                cpr.connections.remove(conn);
9330                conn.client.conProviders.remove(conn);
9331                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9332                return true;
9333            }
9334            return false;
9335        }
9336        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9337        return false;
9338    }
9339
9340    private void checkTime(long startTime, String where) {
9341        long now = SystemClock.elapsedRealtime();
9342        if ((now-startTime) > 1000) {
9343            // If we are taking more than a second, log about it.
9344            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9345        }
9346    }
9347
9348    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9349            String name, IBinder token, boolean stable, int userId) {
9350        ContentProviderRecord cpr;
9351        ContentProviderConnection conn = null;
9352        ProviderInfo cpi = null;
9353
9354        synchronized(this) {
9355            long startTime = SystemClock.elapsedRealtime();
9356
9357            ProcessRecord r = null;
9358            if (caller != null) {
9359                r = getRecordForAppLocked(caller);
9360                if (r == null) {
9361                    throw new SecurityException(
9362                            "Unable to find app for caller " + caller
9363                          + " (pid=" + Binder.getCallingPid()
9364                          + ") when getting content provider " + name);
9365                }
9366            }
9367
9368            boolean checkCrossUser = true;
9369
9370            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9371
9372            // First check if this content provider has been published...
9373            cpr = mProviderMap.getProviderByName(name, userId);
9374            // If that didn't work, check if it exists for user 0 and then
9375            // verify that it's a singleton provider before using it.
9376            if (cpr == null && userId != UserHandle.USER_OWNER) {
9377                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9378                if (cpr != null) {
9379                    cpi = cpr.info;
9380                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9381                            cpi.name, cpi.flags)
9382                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9383                        userId = UserHandle.USER_OWNER;
9384                        checkCrossUser = false;
9385                    } else {
9386                        cpr = null;
9387                        cpi = null;
9388                    }
9389                }
9390            }
9391
9392            boolean providerRunning = cpr != null;
9393            if (providerRunning) {
9394                cpi = cpr.info;
9395                String msg;
9396                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9397                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9398                        != null) {
9399                    throw new SecurityException(msg);
9400                }
9401                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9402
9403                if (r != null && cpr.canRunHere(r)) {
9404                    // This provider has been published or is in the process
9405                    // of being published...  but it is also allowed to run
9406                    // in the caller's process, so don't make a connection
9407                    // and just let the caller instantiate its own instance.
9408                    ContentProviderHolder holder = cpr.newHolder(null);
9409                    // don't give caller the provider object, it needs
9410                    // to make its own.
9411                    holder.provider = null;
9412                    return holder;
9413                }
9414
9415                final long origId = Binder.clearCallingIdentity();
9416
9417                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9418
9419                // In this case the provider instance already exists, so we can
9420                // return it right away.
9421                conn = incProviderCountLocked(r, cpr, token, stable);
9422                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9423                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9424                        // If this is a perceptible app accessing the provider,
9425                        // make sure to count it as being accessed and thus
9426                        // back up on the LRU list.  This is good because
9427                        // content providers are often expensive to start.
9428                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9429                        updateLruProcessLocked(cpr.proc, false, null);
9430                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9431                    }
9432                }
9433
9434                if (cpr.proc != null) {
9435                    if (false) {
9436                        if (cpr.name.flattenToShortString().equals(
9437                                "com.android.providers.calendar/.CalendarProvider2")) {
9438                            Slog.v(TAG, "****************** KILLING "
9439                                + cpr.name.flattenToShortString());
9440                            Process.killProcess(cpr.proc.pid);
9441                        }
9442                    }
9443                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9444                    boolean success = updateOomAdjLocked(cpr.proc);
9445                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9446                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9447                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9448                    // NOTE: there is still a race here where a signal could be
9449                    // pending on the process even though we managed to update its
9450                    // adj level.  Not sure what to do about this, but at least
9451                    // the race is now smaller.
9452                    if (!success) {
9453                        // Uh oh...  it looks like the provider's process
9454                        // has been killed on us.  We need to wait for a new
9455                        // process to be started, and make sure its death
9456                        // doesn't kill our process.
9457                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9458                                + " is crashing; detaching " + r);
9459                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9460                        checkTime(startTime, "getContentProviderImpl: before appDied");
9461                        appDiedLocked(cpr.proc);
9462                        checkTime(startTime, "getContentProviderImpl: after appDied");
9463                        if (!lastRef) {
9464                            // This wasn't the last ref our process had on
9465                            // the provider...  we have now been killed, bail.
9466                            return null;
9467                        }
9468                        providerRunning = false;
9469                        conn = null;
9470                    }
9471                }
9472
9473                Binder.restoreCallingIdentity(origId);
9474            }
9475
9476            boolean singleton;
9477            if (!providerRunning) {
9478                try {
9479                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9480                    cpi = AppGlobals.getPackageManager().
9481                        resolveContentProvider(name,
9482                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9483                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9484                } catch (RemoteException ex) {
9485                }
9486                if (cpi == null) {
9487                    return null;
9488                }
9489                // If the provider is a singleton AND
9490                // (it's a call within the same user || the provider is a
9491                // privileged app)
9492                // Then allow connecting to the singleton provider
9493                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9494                        cpi.name, cpi.flags)
9495                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9496                if (singleton) {
9497                    userId = UserHandle.USER_OWNER;
9498                }
9499                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9500                checkTime(startTime, "getContentProviderImpl: got app info for user");
9501
9502                String msg;
9503                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9504                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9505                        != null) {
9506                    throw new SecurityException(msg);
9507                }
9508                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9509
9510                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9511                        && !cpi.processName.equals("system")) {
9512                    // If this content provider does not run in the system
9513                    // process, and the system is not yet ready to run other
9514                    // processes, then fail fast instead of hanging.
9515                    throw new IllegalArgumentException(
9516                            "Attempt to launch content provider before system ready");
9517                }
9518
9519                // Make sure that the user who owns this provider is running.  If not,
9520                // we don't want to allow it to run.
9521                if (!isUserRunningLocked(userId, false)) {
9522                    Slog.w(TAG, "Unable to launch app "
9523                            + cpi.applicationInfo.packageName + "/"
9524                            + cpi.applicationInfo.uid + " for provider "
9525                            + name + ": user " + userId + " is stopped");
9526                    return null;
9527                }
9528
9529                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9530                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9531                cpr = mProviderMap.getProviderByClass(comp, userId);
9532                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9533                final boolean firstClass = cpr == null;
9534                if (firstClass) {
9535                    final long ident = Binder.clearCallingIdentity();
9536                    try {
9537                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9538                        ApplicationInfo ai =
9539                            AppGlobals.getPackageManager().
9540                                getApplicationInfo(
9541                                        cpi.applicationInfo.packageName,
9542                                        STOCK_PM_FLAGS, userId);
9543                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9544                        if (ai == null) {
9545                            Slog.w(TAG, "No package info for content provider "
9546                                    + cpi.name);
9547                            return null;
9548                        }
9549                        ai = getAppInfoForUser(ai, userId);
9550                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9551                    } catch (RemoteException ex) {
9552                        // pm is in same process, this will never happen.
9553                    } finally {
9554                        Binder.restoreCallingIdentity(ident);
9555                    }
9556                }
9557
9558                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9559
9560                if (r != null && cpr.canRunHere(r)) {
9561                    // If this is a multiprocess provider, then just return its
9562                    // info and allow the caller to instantiate it.  Only do
9563                    // this if the provider is the same user as the caller's
9564                    // process, or can run as root (so can be in any process).
9565                    return cpr.newHolder(null);
9566                }
9567
9568                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9569                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9570                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9571
9572                // This is single process, and our app is now connecting to it.
9573                // See if we are already in the process of launching this
9574                // provider.
9575                final int N = mLaunchingProviders.size();
9576                int i;
9577                for (i = 0; i < N; i++) {
9578                    if (mLaunchingProviders.get(i) == cpr) {
9579                        break;
9580                    }
9581                }
9582
9583                // If the provider is not already being launched, then get it
9584                // started.
9585                if (i >= N) {
9586                    final long origId = Binder.clearCallingIdentity();
9587
9588                    try {
9589                        // Content provider is now in use, its package can't be stopped.
9590                        try {
9591                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9592                            AppGlobals.getPackageManager().setPackageStoppedState(
9593                                    cpr.appInfo.packageName, false, userId);
9594                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9595                        } catch (RemoteException e) {
9596                        } catch (IllegalArgumentException e) {
9597                            Slog.w(TAG, "Failed trying to unstop package "
9598                                    + cpr.appInfo.packageName + ": " + e);
9599                        }
9600
9601                        // Use existing process if already started
9602                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9603                        ProcessRecord proc = getProcessRecordLocked(
9604                                cpi.processName, cpr.appInfo.uid, false);
9605                        if (proc != null && proc.thread != null) {
9606                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9607                                    "Installing in existing process " + proc);
9608                            if (!proc.pubProviders.containsKey(cpi.name)) {
9609                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9610                                proc.pubProviders.put(cpi.name, cpr);
9611                                try {
9612                                    proc.thread.scheduleInstallProvider(cpi);
9613                                } catch (RemoteException e) {
9614                                }
9615                            }
9616                        } else {
9617                            checkTime(startTime, "getContentProviderImpl: before start process");
9618                            proc = startProcessLocked(cpi.processName,
9619                                    cpr.appInfo, false, 0, "content provider",
9620                                    new ComponentName(cpi.applicationInfo.packageName,
9621                                            cpi.name), false, false, false);
9622                            checkTime(startTime, "getContentProviderImpl: after start process");
9623                            if (proc == null) {
9624                                Slog.w(TAG, "Unable to launch app "
9625                                        + cpi.applicationInfo.packageName + "/"
9626                                        + cpi.applicationInfo.uid + " for provider "
9627                                        + name + ": process is bad");
9628                                return null;
9629                            }
9630                        }
9631                        cpr.launchingApp = proc;
9632                        mLaunchingProviders.add(cpr);
9633                    } finally {
9634                        Binder.restoreCallingIdentity(origId);
9635                    }
9636                }
9637
9638                checkTime(startTime, "getContentProviderImpl: updating data structures");
9639
9640                // Make sure the provider is published (the same provider class
9641                // may be published under multiple names).
9642                if (firstClass) {
9643                    mProviderMap.putProviderByClass(comp, cpr);
9644                }
9645
9646                mProviderMap.putProviderByName(name, cpr);
9647                conn = incProviderCountLocked(r, cpr, token, stable);
9648                if (conn != null) {
9649                    conn.waiting = true;
9650                }
9651            }
9652            checkTime(startTime, "getContentProviderImpl: done!");
9653        }
9654
9655        // Wait for the provider to be published...
9656        synchronized (cpr) {
9657            while (cpr.provider == null) {
9658                if (cpr.launchingApp == null) {
9659                    Slog.w(TAG, "Unable to launch app "
9660                            + cpi.applicationInfo.packageName + "/"
9661                            + cpi.applicationInfo.uid + " for provider "
9662                            + name + ": launching app became null");
9663                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9664                            UserHandle.getUserId(cpi.applicationInfo.uid),
9665                            cpi.applicationInfo.packageName,
9666                            cpi.applicationInfo.uid, name);
9667                    return null;
9668                }
9669                try {
9670                    if (DEBUG_MU) Slog.v(TAG_MU,
9671                            "Waiting to start provider " + cpr
9672                            + " launchingApp=" + cpr.launchingApp);
9673                    if (conn != null) {
9674                        conn.waiting = true;
9675                    }
9676                    cpr.wait();
9677                } catch (InterruptedException ex) {
9678                } finally {
9679                    if (conn != null) {
9680                        conn.waiting = false;
9681                    }
9682                }
9683            }
9684        }
9685        return cpr != null ? cpr.newHolder(conn) : null;
9686    }
9687
9688    @Override
9689    public final ContentProviderHolder getContentProvider(
9690            IApplicationThread caller, String name, int userId, boolean stable) {
9691        enforceNotIsolatedCaller("getContentProvider");
9692        if (caller == null) {
9693            String msg = "null IApplicationThread when getting content provider "
9694                    + name;
9695            Slog.w(TAG, msg);
9696            throw new SecurityException(msg);
9697        }
9698        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9699        // with cross-user grant.
9700        return getContentProviderImpl(caller, name, null, stable, userId);
9701    }
9702
9703    public ContentProviderHolder getContentProviderExternal(
9704            String name, int userId, IBinder token) {
9705        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9706            "Do not have permission in call getContentProviderExternal()");
9707        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9708                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9709        return getContentProviderExternalUnchecked(name, token, userId);
9710    }
9711
9712    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9713            IBinder token, int userId) {
9714        return getContentProviderImpl(null, name, token, true, userId);
9715    }
9716
9717    /**
9718     * Drop a content provider from a ProcessRecord's bookkeeping
9719     */
9720    public void removeContentProvider(IBinder connection, boolean stable) {
9721        enforceNotIsolatedCaller("removeContentProvider");
9722        long ident = Binder.clearCallingIdentity();
9723        try {
9724            synchronized (this) {
9725                ContentProviderConnection conn;
9726                try {
9727                    conn = (ContentProviderConnection)connection;
9728                } catch (ClassCastException e) {
9729                    String msg ="removeContentProvider: " + connection
9730                            + " not a ContentProviderConnection";
9731                    Slog.w(TAG, msg);
9732                    throw new IllegalArgumentException(msg);
9733                }
9734                if (conn == null) {
9735                    throw new NullPointerException("connection is null");
9736                }
9737                if (decProviderCountLocked(conn, null, null, stable)) {
9738                    updateOomAdjLocked();
9739                }
9740            }
9741        } finally {
9742            Binder.restoreCallingIdentity(ident);
9743        }
9744    }
9745
9746    public void removeContentProviderExternal(String name, IBinder token) {
9747        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9748            "Do not have permission in call removeContentProviderExternal()");
9749        int userId = UserHandle.getCallingUserId();
9750        long ident = Binder.clearCallingIdentity();
9751        try {
9752            removeContentProviderExternalUnchecked(name, token, userId);
9753        } finally {
9754            Binder.restoreCallingIdentity(ident);
9755        }
9756    }
9757
9758    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9759        synchronized (this) {
9760            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9761            if(cpr == null) {
9762                //remove from mProvidersByClass
9763                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9764                return;
9765            }
9766
9767            //update content provider record entry info
9768            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9769            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9770            if (localCpr.hasExternalProcessHandles()) {
9771                if (localCpr.removeExternalProcessHandleLocked(token)) {
9772                    updateOomAdjLocked();
9773                } else {
9774                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9775                            + " with no external reference for token: "
9776                            + token + ".");
9777                }
9778            } else {
9779                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9780                        + " with no external references.");
9781            }
9782        }
9783    }
9784
9785    public final void publishContentProviders(IApplicationThread caller,
9786            List<ContentProviderHolder> providers) {
9787        if (providers == null) {
9788            return;
9789        }
9790
9791        enforceNotIsolatedCaller("publishContentProviders");
9792        synchronized (this) {
9793            final ProcessRecord r = getRecordForAppLocked(caller);
9794            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9795            if (r == null) {
9796                throw new SecurityException(
9797                        "Unable to find app for caller " + caller
9798                      + " (pid=" + Binder.getCallingPid()
9799                      + ") when publishing content providers");
9800            }
9801
9802            final long origId = Binder.clearCallingIdentity();
9803
9804            final int N = providers.size();
9805            for (int i=0; i<N; i++) {
9806                ContentProviderHolder src = providers.get(i);
9807                if (src == null || src.info == null || src.provider == null) {
9808                    continue;
9809                }
9810                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9811                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9812                if (dst != null) {
9813                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9814                    mProviderMap.putProviderByClass(comp, dst);
9815                    String names[] = dst.info.authority.split(";");
9816                    for (int j = 0; j < names.length; j++) {
9817                        mProviderMap.putProviderByName(names[j], dst);
9818                    }
9819
9820                    int NL = mLaunchingProviders.size();
9821                    int j;
9822                    for (j=0; j<NL; j++) {
9823                        if (mLaunchingProviders.get(j) == dst) {
9824                            mLaunchingProviders.remove(j);
9825                            j--;
9826                            NL--;
9827                        }
9828                    }
9829                    synchronized (dst) {
9830                        dst.provider = src.provider;
9831                        dst.proc = r;
9832                        dst.notifyAll();
9833                    }
9834                    updateOomAdjLocked(r);
9835                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
9836                            src.info.authority);
9837                }
9838            }
9839
9840            Binder.restoreCallingIdentity(origId);
9841        }
9842    }
9843
9844    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9845        ContentProviderConnection conn;
9846        try {
9847            conn = (ContentProviderConnection)connection;
9848        } catch (ClassCastException e) {
9849            String msg ="refContentProvider: " + connection
9850                    + " not a ContentProviderConnection";
9851            Slog.w(TAG, msg);
9852            throw new IllegalArgumentException(msg);
9853        }
9854        if (conn == null) {
9855            throw new NullPointerException("connection is null");
9856        }
9857
9858        synchronized (this) {
9859            if (stable > 0) {
9860                conn.numStableIncs += stable;
9861            }
9862            stable = conn.stableCount + stable;
9863            if (stable < 0) {
9864                throw new IllegalStateException("stableCount < 0: " + stable);
9865            }
9866
9867            if (unstable > 0) {
9868                conn.numUnstableIncs += unstable;
9869            }
9870            unstable = conn.unstableCount + unstable;
9871            if (unstable < 0) {
9872                throw new IllegalStateException("unstableCount < 0: " + unstable);
9873            }
9874
9875            if ((stable+unstable) <= 0) {
9876                throw new IllegalStateException("ref counts can't go to zero here: stable="
9877                        + stable + " unstable=" + unstable);
9878            }
9879            conn.stableCount = stable;
9880            conn.unstableCount = unstable;
9881            return !conn.dead;
9882        }
9883    }
9884
9885    public void unstableProviderDied(IBinder connection) {
9886        ContentProviderConnection conn;
9887        try {
9888            conn = (ContentProviderConnection)connection;
9889        } catch (ClassCastException e) {
9890            String msg ="refContentProvider: " + connection
9891                    + " not a ContentProviderConnection";
9892            Slog.w(TAG, msg);
9893            throw new IllegalArgumentException(msg);
9894        }
9895        if (conn == null) {
9896            throw new NullPointerException("connection is null");
9897        }
9898
9899        // Safely retrieve the content provider associated with the connection.
9900        IContentProvider provider;
9901        synchronized (this) {
9902            provider = conn.provider.provider;
9903        }
9904
9905        if (provider == null) {
9906            // Um, yeah, we're way ahead of you.
9907            return;
9908        }
9909
9910        // Make sure the caller is being honest with us.
9911        if (provider.asBinder().pingBinder()) {
9912            // Er, no, still looks good to us.
9913            synchronized (this) {
9914                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9915                        + " says " + conn + " died, but we don't agree");
9916                return;
9917            }
9918        }
9919
9920        // Well look at that!  It's dead!
9921        synchronized (this) {
9922            if (conn.provider.provider != provider) {
9923                // But something changed...  good enough.
9924                return;
9925            }
9926
9927            ProcessRecord proc = conn.provider.proc;
9928            if (proc == null || proc.thread == null) {
9929                // Seems like the process is already cleaned up.
9930                return;
9931            }
9932
9933            // As far as we're concerned, this is just like receiving a
9934            // death notification...  just a bit prematurely.
9935            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9936                    + ") early provider death");
9937            final long ident = Binder.clearCallingIdentity();
9938            try {
9939                appDiedLocked(proc);
9940            } finally {
9941                Binder.restoreCallingIdentity(ident);
9942            }
9943        }
9944    }
9945
9946    @Override
9947    public void appNotRespondingViaProvider(IBinder connection) {
9948        enforceCallingPermission(
9949                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9950
9951        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9952        if (conn == null) {
9953            Slog.w(TAG, "ContentProviderConnection is null");
9954            return;
9955        }
9956
9957        final ProcessRecord host = conn.provider.proc;
9958        if (host == null) {
9959            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9960            return;
9961        }
9962
9963        final long token = Binder.clearCallingIdentity();
9964        try {
9965            appNotResponding(host, null, null, false, "ContentProvider not responding");
9966        } finally {
9967            Binder.restoreCallingIdentity(token);
9968        }
9969    }
9970
9971    public final void installSystemProviders() {
9972        List<ProviderInfo> providers;
9973        synchronized (this) {
9974            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9975            providers = generateApplicationProvidersLocked(app);
9976            if (providers != null) {
9977                for (int i=providers.size()-1; i>=0; i--) {
9978                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9979                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9980                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9981                                + ": not system .apk");
9982                        providers.remove(i);
9983                    }
9984                }
9985            }
9986        }
9987        if (providers != null) {
9988            mSystemThread.installSystemProviders(providers);
9989        }
9990
9991        mCoreSettingsObserver = new CoreSettingsObserver(this);
9992
9993        //mUsageStatsService.monitorPackages();
9994    }
9995
9996    /**
9997     * Allows apps to retrieve the MIME type of a URI.
9998     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9999     * users, then it does not need permission to access the ContentProvider.
10000     * Either, it needs cross-user uri grants.
10001     *
10002     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10003     *
10004     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10005     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10006     */
10007    public String getProviderMimeType(Uri uri, int userId) {
10008        enforceNotIsolatedCaller("getProviderMimeType");
10009        final String name = uri.getAuthority();
10010        int callingUid = Binder.getCallingUid();
10011        int callingPid = Binder.getCallingPid();
10012        long ident = 0;
10013        boolean clearedIdentity = false;
10014        userId = unsafeConvertIncomingUser(userId);
10015        if (canClearIdentity(callingPid, callingUid, userId)) {
10016            clearedIdentity = true;
10017            ident = Binder.clearCallingIdentity();
10018        }
10019        ContentProviderHolder holder = null;
10020        try {
10021            holder = getContentProviderExternalUnchecked(name, null, userId);
10022            if (holder != null) {
10023                return holder.provider.getType(uri);
10024            }
10025        } catch (RemoteException e) {
10026            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10027            return null;
10028        } finally {
10029            // We need to clear the identity to call removeContentProviderExternalUnchecked
10030            if (!clearedIdentity) {
10031                ident = Binder.clearCallingIdentity();
10032            }
10033            try {
10034                if (holder != null) {
10035                    removeContentProviderExternalUnchecked(name, null, userId);
10036                }
10037            } finally {
10038                Binder.restoreCallingIdentity(ident);
10039            }
10040        }
10041
10042        return null;
10043    }
10044
10045    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10046        if (UserHandle.getUserId(callingUid) == userId) {
10047            return true;
10048        }
10049        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10050                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10051                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10052                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10053                return true;
10054        }
10055        return false;
10056    }
10057
10058    // =========================================================
10059    // GLOBAL MANAGEMENT
10060    // =========================================================
10061
10062    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10063            boolean isolated, int isolatedUid) {
10064        String proc = customProcess != null ? customProcess : info.processName;
10065        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10066        final int userId = UserHandle.getUserId(info.uid);
10067        int uid = info.uid;
10068        if (isolated) {
10069            if (isolatedUid == 0) {
10070                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10071                while (true) {
10072                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10073                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10074                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10075                    }
10076                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10077                    mNextIsolatedProcessUid++;
10078                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10079                        // No process for this uid, use it.
10080                        break;
10081                    }
10082                    stepsLeft--;
10083                    if (stepsLeft <= 0) {
10084                        return null;
10085                    }
10086                }
10087            } else {
10088                // Special case for startIsolatedProcess (internal only), where
10089                // the uid of the isolated process is specified by the caller.
10090                uid = isolatedUid;
10091            }
10092        }
10093        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10094        if (!mBooted && !mBooting
10095                && userId == UserHandle.USER_OWNER
10096                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10097            r.persistent = true;
10098        }
10099        addProcessNameLocked(r);
10100        return r;
10101    }
10102
10103    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10104            String abiOverride) {
10105        ProcessRecord app;
10106        if (!isolated) {
10107            app = getProcessRecordLocked(info.processName, info.uid, true);
10108        } else {
10109            app = null;
10110        }
10111
10112        if (app == null) {
10113            app = newProcessRecordLocked(info, null, isolated, 0);
10114            updateLruProcessLocked(app, false, null);
10115            updateOomAdjLocked();
10116        }
10117
10118        // This package really, really can not be stopped.
10119        try {
10120            AppGlobals.getPackageManager().setPackageStoppedState(
10121                    info.packageName, false, UserHandle.getUserId(app.uid));
10122        } catch (RemoteException e) {
10123        } catch (IllegalArgumentException e) {
10124            Slog.w(TAG, "Failed trying to unstop package "
10125                    + info.packageName + ": " + e);
10126        }
10127
10128        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10129            app.persistent = true;
10130            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10131        }
10132        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10133            mPersistentStartingProcesses.add(app);
10134            startProcessLocked(app, "added application", app.processName, abiOverride,
10135                    null /* entryPoint */, null /* entryPointArgs */);
10136        }
10137
10138        return app;
10139    }
10140
10141    public void unhandledBack() {
10142        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10143                "unhandledBack()");
10144
10145        synchronized(this) {
10146            final long origId = Binder.clearCallingIdentity();
10147            try {
10148                getFocusedStack().unhandledBackLocked();
10149            } finally {
10150                Binder.restoreCallingIdentity(origId);
10151            }
10152        }
10153    }
10154
10155    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10156        enforceNotIsolatedCaller("openContentUri");
10157        final int userId = UserHandle.getCallingUserId();
10158        String name = uri.getAuthority();
10159        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10160        ParcelFileDescriptor pfd = null;
10161        if (cph != null) {
10162            // We record the binder invoker's uid in thread-local storage before
10163            // going to the content provider to open the file.  Later, in the code
10164            // that handles all permissions checks, we look for this uid and use
10165            // that rather than the Activity Manager's own uid.  The effect is that
10166            // we do the check against the caller's permissions even though it looks
10167            // to the content provider like the Activity Manager itself is making
10168            // the request.
10169            Binder token = new Binder();
10170            sCallerIdentity.set(new Identity(
10171                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10172            try {
10173                pfd = cph.provider.openFile(null, uri, "r", null, token);
10174            } catch (FileNotFoundException e) {
10175                // do nothing; pfd will be returned null
10176            } finally {
10177                // Ensure that whatever happens, we clean up the identity state
10178                sCallerIdentity.remove();
10179                // Ensure we're done with the provider.
10180                removeContentProviderExternalUnchecked(name, null, userId);
10181            }
10182        } else {
10183            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10184        }
10185        return pfd;
10186    }
10187
10188    // Actually is sleeping or shutting down or whatever else in the future
10189    // is an inactive state.
10190    public boolean isSleepingOrShuttingDown() {
10191        return isSleeping() || mShuttingDown;
10192    }
10193
10194    public boolean isSleeping() {
10195        return mSleeping;
10196    }
10197
10198    void onWakefulnessChanged(int wakefulness) {
10199        synchronized(this) {
10200            mWakefulness = wakefulness;
10201            updateSleepIfNeededLocked();
10202        }
10203    }
10204
10205    void finishRunningVoiceLocked() {
10206        if (mRunningVoice != null) {
10207            mRunningVoice = null;
10208            mVoiceWakeLock.release();
10209            updateSleepIfNeededLocked();
10210        }
10211    }
10212
10213    void startTimeTrackingFocusedActivityLocked() {
10214        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10215            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10216        }
10217    }
10218
10219    void updateSleepIfNeededLocked() {
10220        if (mSleeping && !shouldSleepLocked()) {
10221            mSleeping = false;
10222            startTimeTrackingFocusedActivityLocked();
10223            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10224            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10225            updateOomAdjLocked();
10226        } else if (!mSleeping && shouldSleepLocked()) {
10227            mSleeping = true;
10228            if (mCurAppTimeTracker != null) {
10229                mCurAppTimeTracker.stop();
10230            }
10231            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10232            mStackSupervisor.goingToSleepLocked();
10233            updateOomAdjLocked();
10234
10235            // Initialize the wake times of all processes.
10236            checkExcessivePowerUsageLocked(false);
10237            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10238            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10239            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10240        }
10241    }
10242
10243    private boolean shouldSleepLocked() {
10244        // Resume applications while running a voice interactor.
10245        if (mRunningVoice != null) {
10246            return false;
10247        }
10248
10249        // TODO: Transform the lock screen state into a sleep token instead.
10250        switch (mWakefulness) {
10251            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10252            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10253            case PowerManagerInternal.WAKEFULNESS_DOZING:
10254                // Pause applications whenever the lock screen is shown or any sleep
10255                // tokens have been acquired.
10256                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10257            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10258            default:
10259                // If we're asleep then pause applications unconditionally.
10260                return true;
10261        }
10262    }
10263
10264    /** Pokes the task persister. */
10265    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10266        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10267            // Never persist the home stack.
10268            return;
10269        }
10270        mTaskPersister.wakeup(task, flush);
10271    }
10272
10273    /** Notifies all listeners when the task stack has changed. */
10274    void notifyTaskStackChangedLocked() {
10275        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10276        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10277        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10278    }
10279
10280    @Override
10281    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10282        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10283    }
10284
10285    @Override
10286    public boolean shutdown(int timeout) {
10287        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10288                != PackageManager.PERMISSION_GRANTED) {
10289            throw new SecurityException("Requires permission "
10290                    + android.Manifest.permission.SHUTDOWN);
10291        }
10292
10293        boolean timedout = false;
10294
10295        synchronized(this) {
10296            mShuttingDown = true;
10297            updateEventDispatchingLocked();
10298            timedout = mStackSupervisor.shutdownLocked(timeout);
10299        }
10300
10301        mAppOpsService.shutdown();
10302        if (mUsageStatsService != null) {
10303            mUsageStatsService.prepareShutdown();
10304        }
10305        mBatteryStatsService.shutdown();
10306        synchronized (this) {
10307            mProcessStats.shutdownLocked();
10308            notifyTaskPersisterLocked(null, true);
10309        }
10310
10311        return timedout;
10312    }
10313
10314    public final void activitySlept(IBinder token) {
10315        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10316
10317        final long origId = Binder.clearCallingIdentity();
10318
10319        synchronized (this) {
10320            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10321            if (r != null) {
10322                mStackSupervisor.activitySleptLocked(r);
10323            }
10324        }
10325
10326        Binder.restoreCallingIdentity(origId);
10327    }
10328
10329    private String lockScreenShownToString() {
10330        switch (mLockScreenShown) {
10331            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10332            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10333            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10334            default: return "Unknown=" + mLockScreenShown;
10335        }
10336    }
10337
10338    void logLockScreen(String msg) {
10339        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10340                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10341                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10342                + " mSleeping=" + mSleeping);
10343    }
10344
10345    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10346        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10347        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10348            boolean wasRunningVoice = mRunningVoice != null;
10349            mRunningVoice = session;
10350            if (!wasRunningVoice) {
10351                mVoiceWakeLock.acquire();
10352                updateSleepIfNeededLocked();
10353            }
10354        }
10355    }
10356
10357    private void updateEventDispatchingLocked() {
10358        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10359    }
10360
10361    public void setLockScreenShown(boolean shown) {
10362        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10363                != PackageManager.PERMISSION_GRANTED) {
10364            throw new SecurityException("Requires permission "
10365                    + android.Manifest.permission.DEVICE_POWER);
10366        }
10367
10368        synchronized(this) {
10369            long ident = Binder.clearCallingIdentity();
10370            try {
10371                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10372                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10373                updateSleepIfNeededLocked();
10374            } finally {
10375                Binder.restoreCallingIdentity(ident);
10376            }
10377        }
10378    }
10379
10380    @Override
10381    public void stopAppSwitches() {
10382        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10383                != PackageManager.PERMISSION_GRANTED) {
10384            throw new SecurityException("Requires permission "
10385                    + android.Manifest.permission.STOP_APP_SWITCHES);
10386        }
10387
10388        synchronized(this) {
10389            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10390                    + APP_SWITCH_DELAY_TIME;
10391            mDidAppSwitch = false;
10392            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10393            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10394            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10395        }
10396    }
10397
10398    public void resumeAppSwitches() {
10399        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10400                != PackageManager.PERMISSION_GRANTED) {
10401            throw new SecurityException("Requires permission "
10402                    + android.Manifest.permission.STOP_APP_SWITCHES);
10403        }
10404
10405        synchronized(this) {
10406            // Note that we don't execute any pending app switches... we will
10407            // let those wait until either the timeout, or the next start
10408            // activity request.
10409            mAppSwitchesAllowedTime = 0;
10410        }
10411    }
10412
10413    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10414            int callingPid, int callingUid, String name) {
10415        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10416            return true;
10417        }
10418
10419        int perm = checkComponentPermission(
10420                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10421                sourceUid, -1, true);
10422        if (perm == PackageManager.PERMISSION_GRANTED) {
10423            return true;
10424        }
10425
10426        // If the actual IPC caller is different from the logical source, then
10427        // also see if they are allowed to control app switches.
10428        if (callingUid != -1 && callingUid != sourceUid) {
10429            perm = checkComponentPermission(
10430                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10431                    callingUid, -1, true);
10432            if (perm == PackageManager.PERMISSION_GRANTED) {
10433                return true;
10434            }
10435        }
10436
10437        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10438        return false;
10439    }
10440
10441    public void setDebugApp(String packageName, boolean waitForDebugger,
10442            boolean persistent) {
10443        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10444                "setDebugApp()");
10445
10446        long ident = Binder.clearCallingIdentity();
10447        try {
10448            // Note that this is not really thread safe if there are multiple
10449            // callers into it at the same time, but that's not a situation we
10450            // care about.
10451            if (persistent) {
10452                final ContentResolver resolver = mContext.getContentResolver();
10453                Settings.Global.putString(
10454                    resolver, Settings.Global.DEBUG_APP,
10455                    packageName);
10456                Settings.Global.putInt(
10457                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10458                    waitForDebugger ? 1 : 0);
10459            }
10460
10461            synchronized (this) {
10462                if (!persistent) {
10463                    mOrigDebugApp = mDebugApp;
10464                    mOrigWaitForDebugger = mWaitForDebugger;
10465                }
10466                mDebugApp = packageName;
10467                mWaitForDebugger = waitForDebugger;
10468                mDebugTransient = !persistent;
10469                if (packageName != null) {
10470                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10471                            false, UserHandle.USER_ALL, "set debug app");
10472                }
10473            }
10474        } finally {
10475            Binder.restoreCallingIdentity(ident);
10476        }
10477    }
10478
10479    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10480        synchronized (this) {
10481            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10482            if (!isDebuggable) {
10483                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10484                    throw new SecurityException("Process not debuggable: " + app.packageName);
10485                }
10486            }
10487
10488            mOpenGlTraceApp = processName;
10489        }
10490    }
10491
10492    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10493        synchronized (this) {
10494            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10495            if (!isDebuggable) {
10496                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10497                    throw new SecurityException("Process not debuggable: " + app.packageName);
10498                }
10499            }
10500            mProfileApp = processName;
10501            mProfileFile = profilerInfo.profileFile;
10502            if (mProfileFd != null) {
10503                try {
10504                    mProfileFd.close();
10505                } catch (IOException e) {
10506                }
10507                mProfileFd = null;
10508            }
10509            mProfileFd = profilerInfo.profileFd;
10510            mSamplingInterval = profilerInfo.samplingInterval;
10511            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10512            mProfileType = 0;
10513        }
10514    }
10515
10516    @Override
10517    public void setAlwaysFinish(boolean enabled) {
10518        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10519                "setAlwaysFinish()");
10520
10521        Settings.Global.putInt(
10522                mContext.getContentResolver(),
10523                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10524
10525        synchronized (this) {
10526            mAlwaysFinishActivities = enabled;
10527        }
10528    }
10529
10530    @Override
10531    public void setActivityController(IActivityController controller) {
10532        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10533                "setActivityController()");
10534        synchronized (this) {
10535            mController = controller;
10536            Watchdog.getInstance().setActivityController(controller);
10537        }
10538    }
10539
10540    @Override
10541    public void setUserIsMonkey(boolean userIsMonkey) {
10542        synchronized (this) {
10543            synchronized (mPidsSelfLocked) {
10544                final int callingPid = Binder.getCallingPid();
10545                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10546                if (precessRecord == null) {
10547                    throw new SecurityException("Unknown process: " + callingPid);
10548                }
10549                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10550                    throw new SecurityException("Only an instrumentation process "
10551                            + "with a UiAutomation can call setUserIsMonkey");
10552                }
10553            }
10554            mUserIsMonkey = userIsMonkey;
10555        }
10556    }
10557
10558    @Override
10559    public boolean isUserAMonkey() {
10560        synchronized (this) {
10561            // If there is a controller also implies the user is a monkey.
10562            return (mUserIsMonkey || mController != null);
10563        }
10564    }
10565
10566    public void requestBugReport() {
10567        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10568        SystemProperties.set("ctl.start", "bugreport");
10569    }
10570
10571    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10572        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10573    }
10574
10575    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10576        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10577            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10578        }
10579        return KEY_DISPATCHING_TIMEOUT;
10580    }
10581
10582    @Override
10583    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10584        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10585                != PackageManager.PERMISSION_GRANTED) {
10586            throw new SecurityException("Requires permission "
10587                    + android.Manifest.permission.FILTER_EVENTS);
10588        }
10589        ProcessRecord proc;
10590        long timeout;
10591        synchronized (this) {
10592            synchronized (mPidsSelfLocked) {
10593                proc = mPidsSelfLocked.get(pid);
10594            }
10595            timeout = getInputDispatchingTimeoutLocked(proc);
10596        }
10597
10598        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10599            return -1;
10600        }
10601
10602        return timeout;
10603    }
10604
10605    /**
10606     * Handle input dispatching timeouts.
10607     * Returns whether input dispatching should be aborted or not.
10608     */
10609    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10610            final ActivityRecord activity, final ActivityRecord parent,
10611            final boolean aboveSystem, String reason) {
10612        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10613                != PackageManager.PERMISSION_GRANTED) {
10614            throw new SecurityException("Requires permission "
10615                    + android.Manifest.permission.FILTER_EVENTS);
10616        }
10617
10618        final String annotation;
10619        if (reason == null) {
10620            annotation = "Input dispatching timed out";
10621        } else {
10622            annotation = "Input dispatching timed out (" + reason + ")";
10623        }
10624
10625        if (proc != null) {
10626            synchronized (this) {
10627                if (proc.debugging) {
10628                    return false;
10629                }
10630
10631                if (mDidDexOpt) {
10632                    // Give more time since we were dexopting.
10633                    mDidDexOpt = false;
10634                    return false;
10635                }
10636
10637                if (proc.instrumentationClass != null) {
10638                    Bundle info = new Bundle();
10639                    info.putString("shortMsg", "keyDispatchingTimedOut");
10640                    info.putString("longMsg", annotation);
10641                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10642                    return true;
10643                }
10644            }
10645            mHandler.post(new Runnable() {
10646                @Override
10647                public void run() {
10648                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10649                }
10650            });
10651        }
10652
10653        return true;
10654    }
10655
10656    @Override
10657    public Bundle getAssistContextExtras(int requestType) {
10658        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10659                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10660        if (pae == null) {
10661            return null;
10662        }
10663        synchronized (pae) {
10664            while (!pae.haveResult) {
10665                try {
10666                    pae.wait();
10667                } catch (InterruptedException e) {
10668                }
10669            }
10670        }
10671        synchronized (this) {
10672            buildAssistBundleLocked(pae, pae.result);
10673            mPendingAssistExtras.remove(pae);
10674            mHandler.removeCallbacks(pae);
10675        }
10676        return pae.extras;
10677    }
10678
10679    @Override
10680    public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
10681        enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId(),
10682                null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT);
10683    }
10684
10685    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10686            IResultReceiver receiver, int userHandle, Bundle args, long timeout) {
10687        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10688                "enqueueAssistContext()");
10689        synchronized (this) {
10690            ActivityRecord activity = getFocusedStack().topActivity();
10691            if (activity == null) {
10692                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10693                return null;
10694            }
10695            if (activity.app == null || activity.app.thread == null) {
10696                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10697                return null;
10698            }
10699            if (activity.app.pid == Binder.getCallingPid()) {
10700                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10701                return null;
10702            }
10703            PendingAssistExtras pae;
10704            Bundle extras = new Bundle();
10705            if (args != null) {
10706                extras.putAll(args);
10707            }
10708            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10709            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10710            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10711            try {
10712                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10713                        requestType);
10714                mPendingAssistExtras.add(pae);
10715                mHandler.postDelayed(pae, timeout);
10716            } catch (RemoteException e) {
10717                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10718                return null;
10719            }
10720            return pae;
10721        }
10722    }
10723
10724    void pendingAssistExtrasTimedOutLocked(PendingAssistExtras pae) {
10725        mPendingAssistExtras.remove(pae);
10726        if (pae.receiver != null) {
10727            // Caller wants result sent back to them.
10728            try {
10729                pae.receiver.send(0, null);
10730            } catch (RemoteException e) {
10731            }
10732        }
10733    }
10734
10735    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10736        if (result != null) {
10737            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10738        }
10739        if (pae.hint != null) {
10740            pae.extras.putBoolean(pae.hint, true);
10741        }
10742    }
10743
10744    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10745            AssistContent content, Uri referrer) {
10746        PendingAssistExtras pae = (PendingAssistExtras)token;
10747        synchronized (pae) {
10748            pae.result = extras;
10749            pae.structure = structure;
10750            pae.content = content;
10751            if (referrer != null) {
10752                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10753            }
10754            pae.haveResult = true;
10755            pae.notifyAll();
10756            if (pae.intent == null && pae.receiver == null) {
10757                // Caller is just waiting for the result.
10758                return;
10759            }
10760        }
10761
10762        // We are now ready to launch the assist activity.
10763        synchronized (this) {
10764            buildAssistBundleLocked(pae, extras);
10765            boolean exists = mPendingAssistExtras.remove(pae);
10766            mHandler.removeCallbacks(pae);
10767            if (!exists) {
10768                // Timed out.
10769                return;
10770            }
10771            if (pae.receiver != null) {
10772                // Caller wants result sent back to them.
10773                Bundle topBundle = new Bundle();
10774                topBundle.putBundle("data", pae.extras);
10775                topBundle.putParcelable("structure", pae.structure);
10776                topBundle.putParcelable("content", pae.content);
10777                try {
10778                    pae.receiver.send(0, topBundle);
10779                } catch (RemoteException e) {
10780                }
10781                return;
10782            }
10783        }
10784        pae.intent.replaceExtras(pae.extras);
10785        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10786                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10787                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10788        closeSystemDialogs("assist");
10789        try {
10790            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10791        } catch (ActivityNotFoundException e) {
10792            Slog.w(TAG, "No activity to handle assist action.", e);
10793        }
10794    }
10795
10796    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10797            Bundle args) {
10798        return enqueueAssistContext(requestType, intent, hint, null, userHandle, args,
10799                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10800    }
10801
10802    public void registerProcessObserver(IProcessObserver observer) {
10803        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10804                "registerProcessObserver()");
10805        synchronized (this) {
10806            mProcessObservers.register(observer);
10807        }
10808    }
10809
10810    @Override
10811    public void unregisterProcessObserver(IProcessObserver observer) {
10812        synchronized (this) {
10813            mProcessObservers.unregister(observer);
10814        }
10815    }
10816
10817    public void registerUidObserver(IUidObserver observer) {
10818        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10819                "registerUidObserver()");
10820        synchronized (this) {
10821            mUidObservers.register(observer);
10822        }
10823    }
10824
10825    @Override
10826    public void unregisterUidObserver(IUidObserver observer) {
10827        synchronized (this) {
10828            mUidObservers.unregister(observer);
10829        }
10830    }
10831
10832    @Override
10833    public boolean convertFromTranslucent(IBinder token) {
10834        final long origId = Binder.clearCallingIdentity();
10835        try {
10836            synchronized (this) {
10837                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10838                if (r == null) {
10839                    return false;
10840                }
10841                final boolean translucentChanged = r.changeWindowTranslucency(true);
10842                if (translucentChanged) {
10843                    r.task.stack.releaseBackgroundResources(r);
10844                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10845                }
10846                mWindowManager.setAppFullscreen(token, true);
10847                return translucentChanged;
10848            }
10849        } finally {
10850            Binder.restoreCallingIdentity(origId);
10851        }
10852    }
10853
10854    @Override
10855    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10856        final long origId = Binder.clearCallingIdentity();
10857        try {
10858            synchronized (this) {
10859                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10860                if (r == null) {
10861                    return false;
10862                }
10863                int index = r.task.mActivities.lastIndexOf(r);
10864                if (index > 0) {
10865                    ActivityRecord under = r.task.mActivities.get(index - 1);
10866                    under.returningOptions = options;
10867                }
10868                final boolean translucentChanged = r.changeWindowTranslucency(false);
10869                if (translucentChanged) {
10870                    r.task.stack.convertActivityToTranslucent(r);
10871                }
10872                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10873                mWindowManager.setAppFullscreen(token, false);
10874                return translucentChanged;
10875            }
10876        } finally {
10877            Binder.restoreCallingIdentity(origId);
10878        }
10879    }
10880
10881    @Override
10882    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10883        final long origId = Binder.clearCallingIdentity();
10884        try {
10885            synchronized (this) {
10886                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10887                if (r != null) {
10888                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10889                }
10890            }
10891            return false;
10892        } finally {
10893            Binder.restoreCallingIdentity(origId);
10894        }
10895    }
10896
10897    @Override
10898    public boolean isBackgroundVisibleBehind(IBinder token) {
10899        final long origId = Binder.clearCallingIdentity();
10900        try {
10901            synchronized (this) {
10902                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10903                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10904                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
10905                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10906                return visible;
10907            }
10908        } finally {
10909            Binder.restoreCallingIdentity(origId);
10910        }
10911    }
10912
10913    @Override
10914    public ActivityOptions getActivityOptions(IBinder token) {
10915        final long origId = Binder.clearCallingIdentity();
10916        try {
10917            synchronized (this) {
10918                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10919                if (r != null) {
10920                    final ActivityOptions activityOptions = r.pendingOptions;
10921                    r.pendingOptions = null;
10922                    return activityOptions;
10923                }
10924                return null;
10925            }
10926        } finally {
10927            Binder.restoreCallingIdentity(origId);
10928        }
10929    }
10930
10931    @Override
10932    public void setImmersive(IBinder token, boolean immersive) {
10933        synchronized(this) {
10934            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10935            if (r == null) {
10936                throw new IllegalArgumentException();
10937            }
10938            r.immersive = immersive;
10939
10940            // update associated state if we're frontmost
10941            if (r == mFocusedActivity) {
10942                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
10943                applyUpdateLockStateLocked(r);
10944            }
10945        }
10946    }
10947
10948    @Override
10949    public boolean isImmersive(IBinder token) {
10950        synchronized (this) {
10951            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10952            if (r == null) {
10953                throw new IllegalArgumentException();
10954            }
10955            return r.immersive;
10956        }
10957    }
10958
10959    public boolean isTopActivityImmersive() {
10960        enforceNotIsolatedCaller("startActivity");
10961        synchronized (this) {
10962            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10963            return (r != null) ? r.immersive : false;
10964        }
10965    }
10966
10967    @Override
10968    public boolean isTopOfTask(IBinder token) {
10969        synchronized (this) {
10970            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10971            if (r == null) {
10972                throw new IllegalArgumentException();
10973            }
10974            return r.task.getTopActivity() == r;
10975        }
10976    }
10977
10978    public final void enterSafeMode() {
10979        synchronized(this) {
10980            // It only makes sense to do this before the system is ready
10981            // and started launching other packages.
10982            if (!mSystemReady) {
10983                try {
10984                    AppGlobals.getPackageManager().enterSafeMode();
10985                } catch (RemoteException e) {
10986                }
10987            }
10988
10989            mSafeMode = true;
10990        }
10991    }
10992
10993    public final void showSafeModeOverlay() {
10994        View v = LayoutInflater.from(mContext).inflate(
10995                com.android.internal.R.layout.safe_mode, null);
10996        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10997        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10998        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10999        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11000        lp.gravity = Gravity.BOTTOM | Gravity.START;
11001        lp.format = v.getBackground().getOpacity();
11002        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11003                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11004        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11005        ((WindowManager)mContext.getSystemService(
11006                Context.WINDOW_SERVICE)).addView(v, lp);
11007    }
11008
11009    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11010        if (!(sender instanceof PendingIntentRecord)) {
11011            return;
11012        }
11013        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11014        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11015        synchronized (stats) {
11016            if (mBatteryStatsService.isOnBattery()) {
11017                mBatteryStatsService.enforceCallingPermission();
11018                int MY_UID = Binder.getCallingUid();
11019                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11020                BatteryStatsImpl.Uid.Pkg pkg =
11021                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11022                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11023                pkg.noteWakeupAlarmLocked(tag);
11024            }
11025        }
11026    }
11027
11028    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11029        if (!(sender instanceof PendingIntentRecord)) {
11030            return;
11031        }
11032        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11033        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11034        synchronized (stats) {
11035            mBatteryStatsService.enforceCallingPermission();
11036            int MY_UID = Binder.getCallingUid();
11037            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11038            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11039        }
11040    }
11041
11042    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11043        if (!(sender instanceof PendingIntentRecord)) {
11044            return;
11045        }
11046        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11047        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11048        synchronized (stats) {
11049            mBatteryStatsService.enforceCallingPermission();
11050            int MY_UID = Binder.getCallingUid();
11051            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11052            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11053        }
11054    }
11055
11056    public boolean killPids(int[] pids, String pReason, boolean secure) {
11057        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11058            throw new SecurityException("killPids only available to the system");
11059        }
11060        String reason = (pReason == null) ? "Unknown" : pReason;
11061        // XXX Note: don't acquire main activity lock here, because the window
11062        // manager calls in with its locks held.
11063
11064        boolean killed = false;
11065        synchronized (mPidsSelfLocked) {
11066            int[] types = new int[pids.length];
11067            int worstType = 0;
11068            for (int i=0; i<pids.length; i++) {
11069                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11070                if (proc != null) {
11071                    int type = proc.setAdj;
11072                    types[i] = type;
11073                    if (type > worstType) {
11074                        worstType = type;
11075                    }
11076                }
11077            }
11078
11079            // If the worst oom_adj is somewhere in the cached proc LRU range,
11080            // then constrain it so we will kill all cached procs.
11081            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11082                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11083                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11084            }
11085
11086            // If this is not a secure call, don't let it kill processes that
11087            // are important.
11088            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11089                worstType = ProcessList.SERVICE_ADJ;
11090            }
11091
11092            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11093            for (int i=0; i<pids.length; i++) {
11094                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11095                if (proc == null) {
11096                    continue;
11097                }
11098                int adj = proc.setAdj;
11099                if (adj >= worstType && !proc.killedByAm) {
11100                    proc.kill(reason, true);
11101                    killed = true;
11102                }
11103            }
11104        }
11105        return killed;
11106    }
11107
11108    @Override
11109    public void killUid(int uid, String reason) {
11110        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11111        synchronized (this) {
11112            final long identity = Binder.clearCallingIdentity();
11113            try {
11114                killPackageProcessesLocked(null, UserHandle.getAppId(uid),
11115                        UserHandle.getUserId(uid),
11116                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11117                        reason != null ? reason : "kill uid");
11118            } finally {
11119                Binder.restoreCallingIdentity(identity);
11120            }
11121        }
11122    }
11123
11124    @Override
11125    public boolean killProcessesBelowForeground(String reason) {
11126        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11127            throw new SecurityException("killProcessesBelowForeground() only available to system");
11128        }
11129
11130        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11131    }
11132
11133    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11134        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11135            throw new SecurityException("killProcessesBelowAdj() only available to system");
11136        }
11137
11138        boolean killed = false;
11139        synchronized (mPidsSelfLocked) {
11140            final int size = mPidsSelfLocked.size();
11141            for (int i = 0; i < size; i++) {
11142                final int pid = mPidsSelfLocked.keyAt(i);
11143                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11144                if (proc == null) continue;
11145
11146                final int adj = proc.setAdj;
11147                if (adj > belowAdj && !proc.killedByAm) {
11148                    proc.kill(reason, true);
11149                    killed = true;
11150                }
11151            }
11152        }
11153        return killed;
11154    }
11155
11156    @Override
11157    public void hang(final IBinder who, boolean allowRestart) {
11158        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11159                != PackageManager.PERMISSION_GRANTED) {
11160            throw new SecurityException("Requires permission "
11161                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11162        }
11163
11164        final IBinder.DeathRecipient death = new DeathRecipient() {
11165            @Override
11166            public void binderDied() {
11167                synchronized (this) {
11168                    notifyAll();
11169                }
11170            }
11171        };
11172
11173        try {
11174            who.linkToDeath(death, 0);
11175        } catch (RemoteException e) {
11176            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11177            return;
11178        }
11179
11180        synchronized (this) {
11181            Watchdog.getInstance().setAllowRestart(allowRestart);
11182            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11183            synchronized (death) {
11184                while (who.isBinderAlive()) {
11185                    try {
11186                        death.wait();
11187                    } catch (InterruptedException e) {
11188                    }
11189                }
11190            }
11191            Watchdog.getInstance().setAllowRestart(true);
11192        }
11193    }
11194
11195    @Override
11196    public void restart() {
11197        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11198                != PackageManager.PERMISSION_GRANTED) {
11199            throw new SecurityException("Requires permission "
11200                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11201        }
11202
11203        Log.i(TAG, "Sending shutdown broadcast...");
11204
11205        BroadcastReceiver br = new BroadcastReceiver() {
11206            @Override public void onReceive(Context context, Intent intent) {
11207                // Now the broadcast is done, finish up the low-level shutdown.
11208                Log.i(TAG, "Shutting down activity manager...");
11209                shutdown(10000);
11210                Log.i(TAG, "Shutdown complete, restarting!");
11211                Process.killProcess(Process.myPid());
11212                System.exit(10);
11213            }
11214        };
11215
11216        // First send the high-level shut down broadcast.
11217        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11218        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11219        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11220        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11221        mContext.sendOrderedBroadcastAsUser(intent,
11222                UserHandle.ALL, null, br, mHandler, 0, null, null);
11223        */
11224        br.onReceive(mContext, intent);
11225    }
11226
11227    private long getLowRamTimeSinceIdle(long now) {
11228        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11229    }
11230
11231    @Override
11232    public void performIdleMaintenance() {
11233        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11234                != PackageManager.PERMISSION_GRANTED) {
11235            throw new SecurityException("Requires permission "
11236                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11237        }
11238
11239        synchronized (this) {
11240            final long now = SystemClock.uptimeMillis();
11241            final long timeSinceLastIdle = now - mLastIdleTime;
11242            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11243            mLastIdleTime = now;
11244            mLowRamTimeSinceLastIdle = 0;
11245            if (mLowRamStartTime != 0) {
11246                mLowRamStartTime = now;
11247            }
11248
11249            StringBuilder sb = new StringBuilder(128);
11250            sb.append("Idle maintenance over ");
11251            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11252            sb.append(" low RAM for ");
11253            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11254            Slog.i(TAG, sb.toString());
11255
11256            // If at least 1/3 of our time since the last idle period has been spent
11257            // with RAM low, then we want to kill processes.
11258            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11259
11260            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11261                ProcessRecord proc = mLruProcesses.get(i);
11262                if (proc.notCachedSinceIdle) {
11263                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11264                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11265                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11266                        if (doKilling && proc.initialIdlePss != 0
11267                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11268                            sb = new StringBuilder(128);
11269                            sb.append("Kill");
11270                            sb.append(proc.processName);
11271                            sb.append(" in idle maint: pss=");
11272                            sb.append(proc.lastPss);
11273                            sb.append(", initialPss=");
11274                            sb.append(proc.initialIdlePss);
11275                            sb.append(", period=");
11276                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11277                            sb.append(", lowRamPeriod=");
11278                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11279                            Slog.wtfQuiet(TAG, sb.toString());
11280                            proc.kill("idle maint (pss " + proc.lastPss
11281                                    + " from " + proc.initialIdlePss + ")", true);
11282                        }
11283                    }
11284                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11285                    proc.notCachedSinceIdle = true;
11286                    proc.initialIdlePss = 0;
11287                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11288                            mTestPssMode, isSleeping(), now);
11289                }
11290            }
11291
11292            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11293            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11294        }
11295    }
11296
11297    private void retrieveSettings() {
11298        final ContentResolver resolver = mContext.getContentResolver();
11299        String debugApp = Settings.Global.getString(
11300            resolver, Settings.Global.DEBUG_APP);
11301        boolean waitForDebugger = Settings.Global.getInt(
11302            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11303        boolean alwaysFinishActivities = Settings.Global.getInt(
11304            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11305        boolean forceRtl = Settings.Global.getInt(
11306                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11307        // Transfer any global setting for forcing RTL layout, into a System Property
11308        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11309
11310        Configuration configuration = new Configuration();
11311        Settings.System.getConfiguration(resolver, configuration);
11312        if (forceRtl) {
11313            // This will take care of setting the correct layout direction flags
11314            configuration.setLayoutDirection(configuration.locale);
11315        }
11316
11317        synchronized (this) {
11318            mDebugApp = mOrigDebugApp = debugApp;
11319            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11320            mAlwaysFinishActivities = alwaysFinishActivities;
11321            // This happens before any activities are started, so we can
11322            // change mConfiguration in-place.
11323            updateConfigurationLocked(configuration, null, false, true);
11324            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11325                    "Initial config: " + mConfiguration);
11326        }
11327    }
11328
11329    /** Loads resources after the current configuration has been set. */
11330    private void loadResourcesOnSystemReady() {
11331        final Resources res = mContext.getResources();
11332        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11333        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11334        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11335    }
11336
11337    public boolean testIsSystemReady() {
11338        // no need to synchronize(this) just to read & return the value
11339        return mSystemReady;
11340    }
11341
11342    private static File getCalledPreBootReceiversFile() {
11343        File dataDir = Environment.getDataDirectory();
11344        File systemDir = new File(dataDir, "system");
11345        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11346        return fname;
11347    }
11348
11349    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11350        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11351        File file = getCalledPreBootReceiversFile();
11352        FileInputStream fis = null;
11353        try {
11354            fis = new FileInputStream(file);
11355            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11356            int fvers = dis.readInt();
11357            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11358                String vers = dis.readUTF();
11359                String codename = dis.readUTF();
11360                String build = dis.readUTF();
11361                if (android.os.Build.VERSION.RELEASE.equals(vers)
11362                        && android.os.Build.VERSION.CODENAME.equals(codename)
11363                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11364                    int num = dis.readInt();
11365                    while (num > 0) {
11366                        num--;
11367                        String pkg = dis.readUTF();
11368                        String cls = dis.readUTF();
11369                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11370                    }
11371                }
11372            }
11373        } catch (FileNotFoundException e) {
11374        } catch (IOException e) {
11375            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11376        } finally {
11377            if (fis != null) {
11378                try {
11379                    fis.close();
11380                } catch (IOException e) {
11381                }
11382            }
11383        }
11384        return lastDoneReceivers;
11385    }
11386
11387    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11388        File file = getCalledPreBootReceiversFile();
11389        FileOutputStream fos = null;
11390        DataOutputStream dos = null;
11391        try {
11392            fos = new FileOutputStream(file);
11393            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11394            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11395            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11396            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11397            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11398            dos.writeInt(list.size());
11399            for (int i=0; i<list.size(); i++) {
11400                dos.writeUTF(list.get(i).getPackageName());
11401                dos.writeUTF(list.get(i).getClassName());
11402            }
11403        } catch (IOException e) {
11404            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11405            file.delete();
11406        } finally {
11407            FileUtils.sync(fos);
11408            if (dos != null) {
11409                try {
11410                    dos.close();
11411                } catch (IOException e) {
11412                    // TODO Auto-generated catch block
11413                    e.printStackTrace();
11414                }
11415            }
11416        }
11417    }
11418
11419    final class PreBootContinuation extends IIntentReceiver.Stub {
11420        final Intent intent;
11421        final Runnable onFinishCallback;
11422        final ArrayList<ComponentName> doneReceivers;
11423        final List<ResolveInfo> ris;
11424        final int[] users;
11425        int lastRi = -1;
11426        int curRi = 0;
11427        int curUser = 0;
11428
11429        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11430                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11431            intent = _intent;
11432            onFinishCallback = _onFinishCallback;
11433            doneReceivers = _doneReceivers;
11434            ris = _ris;
11435            users = _users;
11436        }
11437
11438        void go() {
11439            if (lastRi != curRi) {
11440                ActivityInfo ai = ris.get(curRi).activityInfo;
11441                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11442                intent.setComponent(comp);
11443                doneReceivers.add(comp);
11444                lastRi = curRi;
11445                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11446                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11447            }
11448            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11449                    + " for user " + users[curUser]);
11450            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11451            broadcastIntentLocked(null, null, intent, null, this,
11452                    0, null, null, null, AppOpsManager.OP_NONE,
11453                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11454        }
11455
11456        public void performReceive(Intent intent, int resultCode,
11457                String data, Bundle extras, boolean ordered,
11458                boolean sticky, int sendingUser) {
11459            curUser++;
11460            if (curUser >= users.length) {
11461                curUser = 0;
11462                curRi++;
11463                if (curRi >= ris.size()) {
11464                    // All done sending broadcasts!
11465                    if (onFinishCallback != null) {
11466                        // The raw IIntentReceiver interface is called
11467                        // with the AM lock held, so redispatch to
11468                        // execute our code without the lock.
11469                        mHandler.post(onFinishCallback);
11470                    }
11471                    return;
11472                }
11473            }
11474            go();
11475        }
11476    }
11477
11478    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11479            ArrayList<ComponentName> doneReceivers, int userId) {
11480        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11481        List<ResolveInfo> ris = null;
11482        try {
11483            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11484                    intent, null, 0, userId);
11485        } catch (RemoteException e) {
11486        }
11487        if (ris == null) {
11488            return false;
11489        }
11490        for (int i=ris.size()-1; i>=0; i--) {
11491            if ((ris.get(i).activityInfo.applicationInfo.flags
11492                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11493                ris.remove(i);
11494            }
11495        }
11496        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11497
11498        // For User 0, load the version number. When delivering to a new user, deliver
11499        // to all receivers.
11500        if (userId == UserHandle.USER_OWNER) {
11501            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11502            for (int i=0; i<ris.size(); i++) {
11503                ActivityInfo ai = ris.get(i).activityInfo;
11504                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11505                if (lastDoneReceivers.contains(comp)) {
11506                    // We already did the pre boot receiver for this app with the current
11507                    // platform version, so don't do it again...
11508                    ris.remove(i);
11509                    i--;
11510                    // ...however, do keep it as one that has been done, so we don't
11511                    // forget about it when rewriting the file of last done receivers.
11512                    doneReceivers.add(comp);
11513                }
11514            }
11515        }
11516
11517        if (ris.size() <= 0) {
11518            return false;
11519        }
11520
11521        // If primary user, send broadcast to all available users, else just to userId
11522        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11523                : new int[] { userId };
11524        if (users.length <= 0) {
11525            return false;
11526        }
11527
11528        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11529                ris, users);
11530        cont.go();
11531        return true;
11532    }
11533
11534    public void systemReady(final Runnable goingCallback) {
11535        synchronized(this) {
11536            if (mSystemReady) {
11537                // If we're done calling all the receivers, run the next "boot phase" passed in
11538                // by the SystemServer
11539                if (goingCallback != null) {
11540                    goingCallback.run();
11541                }
11542                return;
11543            }
11544
11545            mLocalDeviceIdleController
11546                    = LocalServices.getService(DeviceIdleController.LocalService.class);
11547
11548            // Make sure we have the current profile info, since it is needed for
11549            // security checks.
11550            updateCurrentProfileIdsLocked();
11551
11552            mRecentTasks.clear();
11553            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11554            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11555            mTaskPersister.startPersisting();
11556
11557            // Check to see if there are any update receivers to run.
11558            if (!mDidUpdate) {
11559                if (mWaitingUpdate) {
11560                    return;
11561                }
11562                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11563                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11564                    public void run() {
11565                        synchronized (ActivityManagerService.this) {
11566                            mDidUpdate = true;
11567                        }
11568                        showBootMessage(mContext.getText(
11569                                R.string.android_upgrading_complete),
11570                                false);
11571                        writeLastDonePreBootReceivers(doneReceivers);
11572                        systemReady(goingCallback);
11573                    }
11574                }, doneReceivers, UserHandle.USER_OWNER);
11575
11576                if (mWaitingUpdate) {
11577                    return;
11578                }
11579                mDidUpdate = true;
11580            }
11581
11582            mAppOpsService.systemReady();
11583            mSystemReady = true;
11584        }
11585
11586        ArrayList<ProcessRecord> procsToKill = null;
11587        synchronized(mPidsSelfLocked) {
11588            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11589                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11590                if (!isAllowedWhileBooting(proc.info)){
11591                    if (procsToKill == null) {
11592                        procsToKill = new ArrayList<ProcessRecord>();
11593                    }
11594                    procsToKill.add(proc);
11595                }
11596            }
11597        }
11598
11599        synchronized(this) {
11600            if (procsToKill != null) {
11601                for (int i=procsToKill.size()-1; i>=0; i--) {
11602                    ProcessRecord proc = procsToKill.get(i);
11603                    Slog.i(TAG, "Removing system update proc: " + proc);
11604                    removeProcessLocked(proc, true, false, "system update done");
11605                }
11606            }
11607
11608            // Now that we have cleaned up any update processes, we
11609            // are ready to start launching real processes and know that
11610            // we won't trample on them any more.
11611            mProcessesReady = true;
11612        }
11613
11614        Slog.i(TAG, "System now ready");
11615        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11616            SystemClock.uptimeMillis());
11617
11618        synchronized(this) {
11619            // Make sure we have no pre-ready processes sitting around.
11620
11621            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11622                ResolveInfo ri = mContext.getPackageManager()
11623                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11624                                STOCK_PM_FLAGS);
11625                CharSequence errorMsg = null;
11626                if (ri != null) {
11627                    ActivityInfo ai = ri.activityInfo;
11628                    ApplicationInfo app = ai.applicationInfo;
11629                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11630                        mTopAction = Intent.ACTION_FACTORY_TEST;
11631                        mTopData = null;
11632                        mTopComponent = new ComponentName(app.packageName,
11633                                ai.name);
11634                    } else {
11635                        errorMsg = mContext.getResources().getText(
11636                                com.android.internal.R.string.factorytest_not_system);
11637                    }
11638                } else {
11639                    errorMsg = mContext.getResources().getText(
11640                            com.android.internal.R.string.factorytest_no_action);
11641                }
11642                if (errorMsg != null) {
11643                    mTopAction = null;
11644                    mTopData = null;
11645                    mTopComponent = null;
11646                    Message msg = Message.obtain();
11647                    msg.what = SHOW_FACTORY_ERROR_MSG;
11648                    msg.getData().putCharSequence("msg", errorMsg);
11649                    mUiHandler.sendMessage(msg);
11650                }
11651            }
11652        }
11653
11654        retrieveSettings();
11655        loadResourcesOnSystemReady();
11656
11657        synchronized (this) {
11658            readGrantedUriPermissionsLocked();
11659        }
11660
11661        if (goingCallback != null) goingCallback.run();
11662
11663        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11664                Integer.toString(mCurrentUserId), mCurrentUserId);
11665        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11666                Integer.toString(mCurrentUserId), mCurrentUserId);
11667        mSystemServiceManager.startUser(mCurrentUserId);
11668
11669        synchronized (this) {
11670            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11671                try {
11672                    List apps = AppGlobals.getPackageManager().
11673                        getPersistentApplications(STOCK_PM_FLAGS);
11674                    if (apps != null) {
11675                        int N = apps.size();
11676                        int i;
11677                        for (i=0; i<N; i++) {
11678                            ApplicationInfo info
11679                                = (ApplicationInfo)apps.get(i);
11680                            if (info != null &&
11681                                    !info.packageName.equals("android")) {
11682                                addAppLocked(info, false, null /* ABI override */);
11683                            }
11684                        }
11685                    }
11686                } catch (RemoteException ex) {
11687                    // pm is in same process, this will never happen.
11688                }
11689            }
11690
11691            // Start up initial activity.
11692            mBooting = true;
11693            startHomeActivityLocked(mCurrentUserId, "systemReady");
11694
11695            try {
11696                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11697                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11698                            + " data partition or your device will be unstable.");
11699                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11700                }
11701            } catch (RemoteException e) {
11702            }
11703
11704            if (!Build.isBuildConsistent()) {
11705                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11706                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11707            }
11708
11709            long ident = Binder.clearCallingIdentity();
11710            try {
11711                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11712                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11713                        | Intent.FLAG_RECEIVER_FOREGROUND);
11714                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11715                broadcastIntentLocked(null, null, intent,
11716                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11717                        null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11718                intent = new Intent(Intent.ACTION_USER_STARTING);
11719                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11720                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11721                broadcastIntentLocked(null, null, intent,
11722                        null, new IIntentReceiver.Stub() {
11723                            @Override
11724                            public void performReceive(Intent intent, int resultCode, String data,
11725                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11726                                    throws RemoteException {
11727                            }
11728                        }, 0, null, null,
11729                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11730                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11731            } catch (Throwable t) {
11732                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11733            } finally {
11734                Binder.restoreCallingIdentity(ident);
11735            }
11736            mStackSupervisor.resumeTopActivitiesLocked();
11737            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11738        }
11739    }
11740
11741    private boolean makeAppCrashingLocked(ProcessRecord app,
11742            String shortMsg, String longMsg, String stackTrace) {
11743        app.crashing = true;
11744        app.crashingReport = generateProcessError(app,
11745                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11746        startAppProblemLocked(app);
11747        app.stopFreezingAllLocked();
11748        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11749    }
11750
11751    private void makeAppNotRespondingLocked(ProcessRecord app,
11752            String activity, String shortMsg, String longMsg) {
11753        app.notResponding = true;
11754        app.notRespondingReport = generateProcessError(app,
11755                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11756                activity, shortMsg, longMsg, null);
11757        startAppProblemLocked(app);
11758        app.stopFreezingAllLocked();
11759    }
11760
11761    /**
11762     * Generate a process error record, suitable for attachment to a ProcessRecord.
11763     *
11764     * @param app The ProcessRecord in which the error occurred.
11765     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11766     *                      ActivityManager.AppErrorStateInfo
11767     * @param activity The activity associated with the crash, if known.
11768     * @param shortMsg Short message describing the crash.
11769     * @param longMsg Long message describing the crash.
11770     * @param stackTrace Full crash stack trace, may be null.
11771     *
11772     * @return Returns a fully-formed AppErrorStateInfo record.
11773     */
11774    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11775            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11776        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11777
11778        report.condition = condition;
11779        report.processName = app.processName;
11780        report.pid = app.pid;
11781        report.uid = app.info.uid;
11782        report.tag = activity;
11783        report.shortMsg = shortMsg;
11784        report.longMsg = longMsg;
11785        report.stackTrace = stackTrace;
11786
11787        return report;
11788    }
11789
11790    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11791        synchronized (this) {
11792            app.crashing = false;
11793            app.crashingReport = null;
11794            app.notResponding = false;
11795            app.notRespondingReport = null;
11796            if (app.anrDialog == fromDialog) {
11797                app.anrDialog = null;
11798            }
11799            if (app.waitDialog == fromDialog) {
11800                app.waitDialog = null;
11801            }
11802            if (app.pid > 0 && app.pid != MY_PID) {
11803                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11804                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11805                app.kill("user request after error", true);
11806            }
11807        }
11808    }
11809
11810    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11811            String shortMsg, String longMsg, String stackTrace) {
11812        long now = SystemClock.uptimeMillis();
11813
11814        Long crashTime;
11815        if (!app.isolated) {
11816            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11817        } else {
11818            crashTime = null;
11819        }
11820        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11821            // This process loses!
11822            Slog.w(TAG, "Process " + app.info.processName
11823                    + " has crashed too many times: killing!");
11824            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11825                    app.userId, app.info.processName, app.uid);
11826            mStackSupervisor.handleAppCrashLocked(app);
11827            if (!app.persistent) {
11828                // We don't want to start this process again until the user
11829                // explicitly does so...  but for persistent process, we really
11830                // need to keep it running.  If a persistent process is actually
11831                // repeatedly crashing, then badness for everyone.
11832                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11833                        app.info.processName);
11834                if (!app.isolated) {
11835                    // XXX We don't have a way to mark isolated processes
11836                    // as bad, since they don't have a peristent identity.
11837                    mBadProcesses.put(app.info.processName, app.uid,
11838                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11839                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11840                }
11841                app.bad = true;
11842                app.removed = true;
11843                // Don't let services in this process be restarted and potentially
11844                // annoy the user repeatedly.  Unless it is persistent, since those
11845                // processes run critical code.
11846                removeProcessLocked(app, false, false, "crash");
11847                mStackSupervisor.resumeTopActivitiesLocked();
11848                return false;
11849            }
11850            mStackSupervisor.resumeTopActivitiesLocked();
11851        } else {
11852            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11853        }
11854
11855        // Bump up the crash count of any services currently running in the proc.
11856        for (int i=app.services.size()-1; i>=0; i--) {
11857            // Any services running in the application need to be placed
11858            // back in the pending list.
11859            ServiceRecord sr = app.services.valueAt(i);
11860            sr.crashCount++;
11861        }
11862
11863        // If the crashing process is what we consider to be the "home process" and it has been
11864        // replaced by a third-party app, clear the package preferred activities from packages
11865        // with a home activity running in the process to prevent a repeatedly crashing app
11866        // from blocking the user to manually clear the list.
11867        final ArrayList<ActivityRecord> activities = app.activities;
11868        if (app == mHomeProcess && activities.size() > 0
11869                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11870            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11871                final ActivityRecord r = activities.get(activityNdx);
11872                if (r.isHomeActivity()) {
11873                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11874                    try {
11875                        ActivityThread.getPackageManager()
11876                                .clearPackagePreferredActivities(r.packageName);
11877                    } catch (RemoteException c) {
11878                        // pm is in same process, this will never happen.
11879                    }
11880                }
11881            }
11882        }
11883
11884        if (!app.isolated) {
11885            // XXX Can't keep track of crash times for isolated processes,
11886            // because they don't have a perisistent identity.
11887            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11888        }
11889
11890        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11891        return true;
11892    }
11893
11894    void startAppProblemLocked(ProcessRecord app) {
11895        // If this app is not running under the current user, then we
11896        // can't give it a report button because that would require
11897        // launching the report UI under a different user.
11898        app.errorReportReceiver = null;
11899
11900        for (int userId : mCurrentProfileIds) {
11901            if (app.userId == userId) {
11902                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11903                        mContext, app.info.packageName, app.info.flags);
11904            }
11905        }
11906        skipCurrentReceiverLocked(app);
11907    }
11908
11909    void skipCurrentReceiverLocked(ProcessRecord app) {
11910        for (BroadcastQueue queue : mBroadcastQueues) {
11911            queue.skipCurrentReceiverLocked(app);
11912        }
11913    }
11914
11915    /**
11916     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11917     * The application process will exit immediately after this call returns.
11918     * @param app object of the crashing app, null for the system server
11919     * @param crashInfo describing the exception
11920     */
11921    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11922        ProcessRecord r = findAppProcess(app, "Crash");
11923        final String processName = app == null ? "system_server"
11924                : (r == null ? "unknown" : r.processName);
11925
11926        handleApplicationCrashInner("crash", r, processName, crashInfo);
11927    }
11928
11929    /* Native crash reporting uses this inner version because it needs to be somewhat
11930     * decoupled from the AM-managed cleanup lifecycle
11931     */
11932    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11933            ApplicationErrorReport.CrashInfo crashInfo) {
11934        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11935                UserHandle.getUserId(Binder.getCallingUid()), processName,
11936                r == null ? -1 : r.info.flags,
11937                crashInfo.exceptionClassName,
11938                crashInfo.exceptionMessage,
11939                crashInfo.throwFileName,
11940                crashInfo.throwLineNumber);
11941
11942        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11943
11944        crashApplication(r, crashInfo);
11945    }
11946
11947    public void handleApplicationStrictModeViolation(
11948            IBinder app,
11949            int violationMask,
11950            StrictMode.ViolationInfo info) {
11951        ProcessRecord r = findAppProcess(app, "StrictMode");
11952        if (r == null) {
11953            return;
11954        }
11955
11956        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11957            Integer stackFingerprint = info.hashCode();
11958            boolean logIt = true;
11959            synchronized (mAlreadyLoggedViolatedStacks) {
11960                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11961                    logIt = false;
11962                    // TODO: sub-sample into EventLog for these, with
11963                    // the info.durationMillis?  Then we'd get
11964                    // the relative pain numbers, without logging all
11965                    // the stack traces repeatedly.  We'd want to do
11966                    // likewise in the client code, which also does
11967                    // dup suppression, before the Binder call.
11968                } else {
11969                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11970                        mAlreadyLoggedViolatedStacks.clear();
11971                    }
11972                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11973                }
11974            }
11975            if (logIt) {
11976                logStrictModeViolationToDropBox(r, info);
11977            }
11978        }
11979
11980        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11981            AppErrorResult result = new AppErrorResult();
11982            synchronized (this) {
11983                final long origId = Binder.clearCallingIdentity();
11984
11985                Message msg = Message.obtain();
11986                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11987                HashMap<String, Object> data = new HashMap<String, Object>();
11988                data.put("result", result);
11989                data.put("app", r);
11990                data.put("violationMask", violationMask);
11991                data.put("info", info);
11992                msg.obj = data;
11993                mUiHandler.sendMessage(msg);
11994
11995                Binder.restoreCallingIdentity(origId);
11996            }
11997            int res = result.get();
11998            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11999        }
12000    }
12001
12002    // Depending on the policy in effect, there could be a bunch of
12003    // these in quick succession so we try to batch these together to
12004    // minimize disk writes, number of dropbox entries, and maximize
12005    // compression, by having more fewer, larger records.
12006    private void logStrictModeViolationToDropBox(
12007            ProcessRecord process,
12008            StrictMode.ViolationInfo info) {
12009        if (info == null) {
12010            return;
12011        }
12012        final boolean isSystemApp = process == null ||
12013                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12014                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12015        final String processName = process == null ? "unknown" : process.processName;
12016        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12017        final DropBoxManager dbox = (DropBoxManager)
12018                mContext.getSystemService(Context.DROPBOX_SERVICE);
12019
12020        // Exit early if the dropbox isn't configured to accept this report type.
12021        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12022
12023        boolean bufferWasEmpty;
12024        boolean needsFlush;
12025        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12026        synchronized (sb) {
12027            bufferWasEmpty = sb.length() == 0;
12028            appendDropBoxProcessHeaders(process, processName, sb);
12029            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12030            sb.append("System-App: ").append(isSystemApp).append("\n");
12031            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12032            if (info.violationNumThisLoop != 0) {
12033                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12034            }
12035            if (info.numAnimationsRunning != 0) {
12036                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12037            }
12038            if (info.broadcastIntentAction != null) {
12039                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12040            }
12041            if (info.durationMillis != -1) {
12042                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12043            }
12044            if (info.numInstances != -1) {
12045                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12046            }
12047            if (info.tags != null) {
12048                for (String tag : info.tags) {
12049                    sb.append("Span-Tag: ").append(tag).append("\n");
12050                }
12051            }
12052            sb.append("\n");
12053            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12054                sb.append(info.crashInfo.stackTrace);
12055                sb.append("\n");
12056            }
12057            if (info.message != null) {
12058                sb.append(info.message);
12059                sb.append("\n");
12060            }
12061
12062            // Only buffer up to ~64k.  Various logging bits truncate
12063            // things at 128k.
12064            needsFlush = (sb.length() > 64 * 1024);
12065        }
12066
12067        // Flush immediately if the buffer's grown too large, or this
12068        // is a non-system app.  Non-system apps are isolated with a
12069        // different tag & policy and not batched.
12070        //
12071        // Batching is useful during internal testing with
12072        // StrictMode settings turned up high.  Without batching,
12073        // thousands of separate files could be created on boot.
12074        if (!isSystemApp || needsFlush) {
12075            new Thread("Error dump: " + dropboxTag) {
12076                @Override
12077                public void run() {
12078                    String report;
12079                    synchronized (sb) {
12080                        report = sb.toString();
12081                        sb.delete(0, sb.length());
12082                        sb.trimToSize();
12083                    }
12084                    if (report.length() != 0) {
12085                        dbox.addText(dropboxTag, report);
12086                    }
12087                }
12088            }.start();
12089            return;
12090        }
12091
12092        // System app batching:
12093        if (!bufferWasEmpty) {
12094            // An existing dropbox-writing thread is outstanding, so
12095            // we don't need to start it up.  The existing thread will
12096            // catch the buffer appends we just did.
12097            return;
12098        }
12099
12100        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12101        // (After this point, we shouldn't access AMS internal data structures.)
12102        new Thread("Error dump: " + dropboxTag) {
12103            @Override
12104            public void run() {
12105                // 5 second sleep to let stacks arrive and be batched together
12106                try {
12107                    Thread.sleep(5000);  // 5 seconds
12108                } catch (InterruptedException e) {}
12109
12110                String errorReport;
12111                synchronized (mStrictModeBuffer) {
12112                    errorReport = mStrictModeBuffer.toString();
12113                    if (errorReport.length() == 0) {
12114                        return;
12115                    }
12116                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12117                    mStrictModeBuffer.trimToSize();
12118                }
12119                dbox.addText(dropboxTag, errorReport);
12120            }
12121        }.start();
12122    }
12123
12124    /**
12125     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12126     * @param app object of the crashing app, null for the system server
12127     * @param tag reported by the caller
12128     * @param system whether this wtf is coming from the system
12129     * @param crashInfo describing the context of the error
12130     * @return true if the process should exit immediately (WTF is fatal)
12131     */
12132    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12133            final ApplicationErrorReport.CrashInfo crashInfo) {
12134        final int callingUid = Binder.getCallingUid();
12135        final int callingPid = Binder.getCallingPid();
12136
12137        if (system) {
12138            // If this is coming from the system, we could very well have low-level
12139            // system locks held, so we want to do this all asynchronously.  And we
12140            // never want this to become fatal, so there is that too.
12141            mHandler.post(new Runnable() {
12142                @Override public void run() {
12143                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12144                }
12145            });
12146            return false;
12147        }
12148
12149        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12150                crashInfo);
12151
12152        if (r != null && r.pid != Process.myPid() &&
12153                Settings.Global.getInt(mContext.getContentResolver(),
12154                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12155            crashApplication(r, crashInfo);
12156            return true;
12157        } else {
12158            return false;
12159        }
12160    }
12161
12162    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12163            final ApplicationErrorReport.CrashInfo crashInfo) {
12164        final ProcessRecord r = findAppProcess(app, "WTF");
12165        final String processName = app == null ? "system_server"
12166                : (r == null ? "unknown" : r.processName);
12167
12168        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12169                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12170
12171        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12172
12173        return r;
12174    }
12175
12176    /**
12177     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12178     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12179     */
12180    private ProcessRecord findAppProcess(IBinder app, String reason) {
12181        if (app == null) {
12182            return null;
12183        }
12184
12185        synchronized (this) {
12186            final int NP = mProcessNames.getMap().size();
12187            for (int ip=0; ip<NP; ip++) {
12188                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12189                final int NA = apps.size();
12190                for (int ia=0; ia<NA; ia++) {
12191                    ProcessRecord p = apps.valueAt(ia);
12192                    if (p.thread != null && p.thread.asBinder() == app) {
12193                        return p;
12194                    }
12195                }
12196            }
12197
12198            Slog.w(TAG, "Can't find mystery application for " + reason
12199                    + " from pid=" + Binder.getCallingPid()
12200                    + " uid=" + Binder.getCallingUid() + ": " + app);
12201            return null;
12202        }
12203    }
12204
12205    /**
12206     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12207     * to append various headers to the dropbox log text.
12208     */
12209    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12210            StringBuilder sb) {
12211        // Watchdog thread ends up invoking this function (with
12212        // a null ProcessRecord) to add the stack file to dropbox.
12213        // Do not acquire a lock on this (am) in such cases, as it
12214        // could cause a potential deadlock, if and when watchdog
12215        // is invoked due to unavailability of lock on am and it
12216        // would prevent watchdog from killing system_server.
12217        if (process == null) {
12218            sb.append("Process: ").append(processName).append("\n");
12219            return;
12220        }
12221        // Note: ProcessRecord 'process' is guarded by the service
12222        // instance.  (notably process.pkgList, which could otherwise change
12223        // concurrently during execution of this method)
12224        synchronized (this) {
12225            sb.append("Process: ").append(processName).append("\n");
12226            int flags = process.info.flags;
12227            IPackageManager pm = AppGlobals.getPackageManager();
12228            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12229            for (int ip=0; ip<process.pkgList.size(); ip++) {
12230                String pkg = process.pkgList.keyAt(ip);
12231                sb.append("Package: ").append(pkg);
12232                try {
12233                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12234                    if (pi != null) {
12235                        sb.append(" v").append(pi.versionCode);
12236                        if (pi.versionName != null) {
12237                            sb.append(" (").append(pi.versionName).append(")");
12238                        }
12239                    }
12240                } catch (RemoteException e) {
12241                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12242                }
12243                sb.append("\n");
12244            }
12245        }
12246    }
12247
12248    private static String processClass(ProcessRecord process) {
12249        if (process == null || process.pid == MY_PID) {
12250            return "system_server";
12251        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12252            return "system_app";
12253        } else {
12254            return "data_app";
12255        }
12256    }
12257
12258    /**
12259     * Write a description of an error (crash, WTF, ANR) to the drop box.
12260     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12261     * @param process which caused the error, null means the system server
12262     * @param activity which triggered the error, null if unknown
12263     * @param parent activity related to the error, null if unknown
12264     * @param subject line related to the error, null if absent
12265     * @param report in long form describing the error, null if absent
12266     * @param logFile to include in the report, null if none
12267     * @param crashInfo giving an application stack trace, null if absent
12268     */
12269    public void addErrorToDropBox(String eventType,
12270            ProcessRecord process, String processName, ActivityRecord activity,
12271            ActivityRecord parent, String subject,
12272            final String report, final File logFile,
12273            final ApplicationErrorReport.CrashInfo crashInfo) {
12274        // NOTE -- this must never acquire the ActivityManagerService lock,
12275        // otherwise the watchdog may be prevented from resetting the system.
12276
12277        final String dropboxTag = processClass(process) + "_" + eventType;
12278        final DropBoxManager dbox = (DropBoxManager)
12279                mContext.getSystemService(Context.DROPBOX_SERVICE);
12280
12281        // Exit early if the dropbox isn't configured to accept this report type.
12282        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12283
12284        final StringBuilder sb = new StringBuilder(1024);
12285        appendDropBoxProcessHeaders(process, processName, sb);
12286        if (activity != null) {
12287            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12288        }
12289        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12290            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12291        }
12292        if (parent != null && parent != activity) {
12293            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12294        }
12295        if (subject != null) {
12296            sb.append("Subject: ").append(subject).append("\n");
12297        }
12298        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12299        if (Debug.isDebuggerConnected()) {
12300            sb.append("Debugger: Connected\n");
12301        }
12302        sb.append("\n");
12303
12304        // Do the rest in a worker thread to avoid blocking the caller on I/O
12305        // (After this point, we shouldn't access AMS internal data structures.)
12306        Thread worker = new Thread("Error dump: " + dropboxTag) {
12307            @Override
12308            public void run() {
12309                if (report != null) {
12310                    sb.append(report);
12311                }
12312                if (logFile != null) {
12313                    try {
12314                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12315                                    "\n\n[[TRUNCATED]]"));
12316                    } catch (IOException e) {
12317                        Slog.e(TAG, "Error reading " + logFile, e);
12318                    }
12319                }
12320                if (crashInfo != null && crashInfo.stackTrace != null) {
12321                    sb.append(crashInfo.stackTrace);
12322                }
12323
12324                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12325                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12326                if (lines > 0) {
12327                    sb.append("\n");
12328
12329                    // Merge several logcat streams, and take the last N lines
12330                    InputStreamReader input = null;
12331                    try {
12332                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12333                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12334                                "-b", "crash",
12335                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12336
12337                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12338                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12339                        input = new InputStreamReader(logcat.getInputStream());
12340
12341                        int num;
12342                        char[] buf = new char[8192];
12343                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12344                    } catch (IOException e) {
12345                        Slog.e(TAG, "Error running logcat", e);
12346                    } finally {
12347                        if (input != null) try { input.close(); } catch (IOException e) {}
12348                    }
12349                }
12350
12351                dbox.addText(dropboxTag, sb.toString());
12352            }
12353        };
12354
12355        if (process == null) {
12356            // If process is null, we are being called from some internal code
12357            // and may be about to die -- run this synchronously.
12358            worker.run();
12359        } else {
12360            worker.start();
12361        }
12362    }
12363
12364    /**
12365     * Bring up the "unexpected error" dialog box for a crashing app.
12366     * Deal with edge cases (intercepts from instrumented applications,
12367     * ActivityController, error intent receivers, that sort of thing).
12368     * @param r the application crashing
12369     * @param crashInfo describing the failure
12370     */
12371    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12372        long timeMillis = System.currentTimeMillis();
12373        String shortMsg = crashInfo.exceptionClassName;
12374        String longMsg = crashInfo.exceptionMessage;
12375        String stackTrace = crashInfo.stackTrace;
12376        if (shortMsg != null && longMsg != null) {
12377            longMsg = shortMsg + ": " + longMsg;
12378        } else if (shortMsg != null) {
12379            longMsg = shortMsg;
12380        }
12381
12382        AppErrorResult result = new AppErrorResult();
12383        synchronized (this) {
12384            if (mController != null) {
12385                try {
12386                    String name = r != null ? r.processName : null;
12387                    int pid = r != null ? r.pid : Binder.getCallingPid();
12388                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12389                    if (!mController.appCrashed(name, pid,
12390                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12391                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12392                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12393                            Slog.w(TAG, "Skip killing native crashed app " + name
12394                                    + "(" + pid + ") during testing");
12395                        } else {
12396                            Slog.w(TAG, "Force-killing crashed app " + name
12397                                    + " at watcher's request");
12398                            if (r != null) {
12399                                r.kill("crash", true);
12400                            } else {
12401                                // Huh.
12402                                Process.killProcess(pid);
12403                                Process.killProcessGroup(uid, pid);
12404                            }
12405                        }
12406                        return;
12407                    }
12408                } catch (RemoteException e) {
12409                    mController = null;
12410                    Watchdog.getInstance().setActivityController(null);
12411                }
12412            }
12413
12414            final long origId = Binder.clearCallingIdentity();
12415
12416            // If this process is running instrumentation, finish it.
12417            if (r != null && r.instrumentationClass != null) {
12418                Slog.w(TAG, "Error in app " + r.processName
12419                      + " running instrumentation " + r.instrumentationClass + ":");
12420                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12421                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12422                Bundle info = new Bundle();
12423                info.putString("shortMsg", shortMsg);
12424                info.putString("longMsg", longMsg);
12425                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12426                Binder.restoreCallingIdentity(origId);
12427                return;
12428            }
12429
12430            // Log crash in battery stats.
12431            if (r != null) {
12432                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12433            }
12434
12435            // If we can't identify the process or it's already exceeded its crash quota,
12436            // quit right away without showing a crash dialog.
12437            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12438                Binder.restoreCallingIdentity(origId);
12439                return;
12440            }
12441
12442            Message msg = Message.obtain();
12443            msg.what = SHOW_ERROR_MSG;
12444            HashMap data = new HashMap();
12445            data.put("result", result);
12446            data.put("app", r);
12447            msg.obj = data;
12448            mUiHandler.sendMessage(msg);
12449
12450            Binder.restoreCallingIdentity(origId);
12451        }
12452
12453        int res = result.get();
12454
12455        Intent appErrorIntent = null;
12456        synchronized (this) {
12457            if (r != null && !r.isolated) {
12458                // XXX Can't keep track of crash time for isolated processes,
12459                // since they don't have a persistent identity.
12460                mProcessCrashTimes.put(r.info.processName, r.uid,
12461                        SystemClock.uptimeMillis());
12462            }
12463            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12464                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12465            }
12466        }
12467
12468        if (appErrorIntent != null) {
12469            try {
12470                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12471            } catch (ActivityNotFoundException e) {
12472                Slog.w(TAG, "bug report receiver dissappeared", e);
12473            }
12474        }
12475    }
12476
12477    Intent createAppErrorIntentLocked(ProcessRecord r,
12478            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12479        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12480        if (report == null) {
12481            return null;
12482        }
12483        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12484        result.setComponent(r.errorReportReceiver);
12485        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12486        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12487        return result;
12488    }
12489
12490    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12491            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12492        if (r.errorReportReceiver == null) {
12493            return null;
12494        }
12495
12496        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12497            return null;
12498        }
12499
12500        ApplicationErrorReport report = new ApplicationErrorReport();
12501        report.packageName = r.info.packageName;
12502        report.installerPackageName = r.errorReportReceiver.getPackageName();
12503        report.processName = r.processName;
12504        report.time = timeMillis;
12505        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12506
12507        if (r.crashing || r.forceCrashReport) {
12508            report.type = ApplicationErrorReport.TYPE_CRASH;
12509            report.crashInfo = crashInfo;
12510        } else if (r.notResponding) {
12511            report.type = ApplicationErrorReport.TYPE_ANR;
12512            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12513
12514            report.anrInfo.activity = r.notRespondingReport.tag;
12515            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12516            report.anrInfo.info = r.notRespondingReport.longMsg;
12517        }
12518
12519        return report;
12520    }
12521
12522    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12523        enforceNotIsolatedCaller("getProcessesInErrorState");
12524        // assume our apps are happy - lazy create the list
12525        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12526
12527        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12528                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12529        int userId = UserHandle.getUserId(Binder.getCallingUid());
12530
12531        synchronized (this) {
12532
12533            // iterate across all processes
12534            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12535                ProcessRecord app = mLruProcesses.get(i);
12536                if (!allUsers && app.userId != userId) {
12537                    continue;
12538                }
12539                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12540                    // This one's in trouble, so we'll generate a report for it
12541                    // crashes are higher priority (in case there's a crash *and* an anr)
12542                    ActivityManager.ProcessErrorStateInfo report = null;
12543                    if (app.crashing) {
12544                        report = app.crashingReport;
12545                    } else if (app.notResponding) {
12546                        report = app.notRespondingReport;
12547                    }
12548
12549                    if (report != null) {
12550                        if (errList == null) {
12551                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12552                        }
12553                        errList.add(report);
12554                    } else {
12555                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12556                                " crashing = " + app.crashing +
12557                                " notResponding = " + app.notResponding);
12558                    }
12559                }
12560            }
12561        }
12562
12563        return errList;
12564    }
12565
12566    static int procStateToImportance(int procState, int memAdj,
12567            ActivityManager.RunningAppProcessInfo currApp) {
12568        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12569        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12570            currApp.lru = memAdj;
12571        } else {
12572            currApp.lru = 0;
12573        }
12574        return imp;
12575    }
12576
12577    private void fillInProcMemInfo(ProcessRecord app,
12578            ActivityManager.RunningAppProcessInfo outInfo) {
12579        outInfo.pid = app.pid;
12580        outInfo.uid = app.info.uid;
12581        if (mHeavyWeightProcess == app) {
12582            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12583        }
12584        if (app.persistent) {
12585            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12586        }
12587        if (app.activities.size() > 0) {
12588            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12589        }
12590        outInfo.lastTrimLevel = app.trimMemoryLevel;
12591        int adj = app.curAdj;
12592        int procState = app.curProcState;
12593        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12594        outInfo.importanceReasonCode = app.adjTypeCode;
12595        outInfo.processState = app.curProcState;
12596    }
12597
12598    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12599        enforceNotIsolatedCaller("getRunningAppProcesses");
12600
12601        final int callingUid = Binder.getCallingUid();
12602
12603        // Lazy instantiation of list
12604        List<ActivityManager.RunningAppProcessInfo> runList = null;
12605        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12606                callingUid) == PackageManager.PERMISSION_GRANTED;
12607        final int userId = UserHandle.getUserId(callingUid);
12608        final boolean allUids = isGetTasksAllowed(
12609                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12610
12611        synchronized (this) {
12612            // Iterate across all processes
12613            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12614                ProcessRecord app = mLruProcesses.get(i);
12615                if ((!allUsers && app.userId != userId)
12616                        || (!allUids && app.uid != callingUid)) {
12617                    continue;
12618                }
12619                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12620                    // Generate process state info for running application
12621                    ActivityManager.RunningAppProcessInfo currApp =
12622                        new ActivityManager.RunningAppProcessInfo(app.processName,
12623                                app.pid, app.getPackageList());
12624                    fillInProcMemInfo(app, currApp);
12625                    if (app.adjSource instanceof ProcessRecord) {
12626                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12627                        currApp.importanceReasonImportance =
12628                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12629                                        app.adjSourceProcState);
12630                    } else if (app.adjSource instanceof ActivityRecord) {
12631                        ActivityRecord r = (ActivityRecord)app.adjSource;
12632                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12633                    }
12634                    if (app.adjTarget instanceof ComponentName) {
12635                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12636                    }
12637                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12638                    //        + " lru=" + currApp.lru);
12639                    if (runList == null) {
12640                        runList = new ArrayList<>();
12641                    }
12642                    runList.add(currApp);
12643                }
12644            }
12645        }
12646        return runList;
12647    }
12648
12649    public List<ApplicationInfo> getRunningExternalApplications() {
12650        enforceNotIsolatedCaller("getRunningExternalApplications");
12651        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12652        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12653        if (runningApps != null && runningApps.size() > 0) {
12654            Set<String> extList = new HashSet<String>();
12655            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12656                if (app.pkgList != null) {
12657                    for (String pkg : app.pkgList) {
12658                        extList.add(pkg);
12659                    }
12660                }
12661            }
12662            IPackageManager pm = AppGlobals.getPackageManager();
12663            for (String pkg : extList) {
12664                try {
12665                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12666                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12667                        retList.add(info);
12668                    }
12669                } catch (RemoteException e) {
12670                }
12671            }
12672        }
12673        return retList;
12674    }
12675
12676    @Override
12677    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12678        enforceNotIsolatedCaller("getMyMemoryState");
12679        synchronized (this) {
12680            ProcessRecord proc;
12681            synchronized (mPidsSelfLocked) {
12682                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12683            }
12684            fillInProcMemInfo(proc, outInfo);
12685        }
12686    }
12687
12688    @Override
12689    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12690        if (checkCallingPermission(android.Manifest.permission.DUMP)
12691                != PackageManager.PERMISSION_GRANTED) {
12692            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12693                    + Binder.getCallingPid()
12694                    + ", uid=" + Binder.getCallingUid()
12695                    + " without permission "
12696                    + android.Manifest.permission.DUMP);
12697            return;
12698        }
12699
12700        boolean dumpAll = false;
12701        boolean dumpClient = false;
12702        String dumpPackage = null;
12703
12704        int opti = 0;
12705        while (opti < args.length) {
12706            String opt = args[opti];
12707            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12708                break;
12709            }
12710            opti++;
12711            if ("-a".equals(opt)) {
12712                dumpAll = true;
12713            } else if ("-c".equals(opt)) {
12714                dumpClient = true;
12715            } else if ("-p".equals(opt)) {
12716                if (opti < args.length) {
12717                    dumpPackage = args[opti];
12718                    opti++;
12719                } else {
12720                    pw.println("Error: -p option requires package argument");
12721                    return;
12722                }
12723                dumpClient = true;
12724            } else if ("-h".equals(opt)) {
12725                pw.println("Activity manager dump options:");
12726                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12727                pw.println("  cmd may be one of:");
12728                pw.println("    a[ctivities]: activity stack state");
12729                pw.println("    r[recents]: recent activities state");
12730                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12731                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12732                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12733                pw.println("    o[om]: out of memory management");
12734                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12735                pw.println("    provider [COMP_SPEC]: provider client-side state");
12736                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12737                pw.println("    as[sociations]: tracked app associations");
12738                pw.println("    service [COMP_SPEC]: service client-side state");
12739                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12740                pw.println("    all: dump all activities");
12741                pw.println("    top: dump the top activity");
12742                pw.println("    write: write all pending state to storage");
12743                pw.println("    track-associations: enable association tracking");
12744                pw.println("    untrack-associations: disable and clear association tracking");
12745                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12746                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12747                pw.println("    a partial substring in a component name, a");
12748                pw.println("    hex object identifier.");
12749                pw.println("  -a: include all available server state.");
12750                pw.println("  -c: include client state.");
12751                pw.println("  -p: limit output to given package.");
12752                return;
12753            } else {
12754                pw.println("Unknown argument: " + opt + "; use -h for help");
12755            }
12756        }
12757
12758        long origId = Binder.clearCallingIdentity();
12759        boolean more = false;
12760        // Is the caller requesting to dump a particular piece of data?
12761        if (opti < args.length) {
12762            String cmd = args[opti];
12763            opti++;
12764            if ("activities".equals(cmd) || "a".equals(cmd)) {
12765                synchronized (this) {
12766                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12767                }
12768            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12769                synchronized (this) {
12770                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12771                }
12772            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12773                String[] newArgs;
12774                String name;
12775                if (opti >= args.length) {
12776                    name = null;
12777                    newArgs = EMPTY_STRING_ARRAY;
12778                } else {
12779                    dumpPackage = args[opti];
12780                    opti++;
12781                    newArgs = new String[args.length - opti];
12782                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12783                            args.length - opti);
12784                }
12785                synchronized (this) {
12786                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12787                }
12788            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12789                String[] newArgs;
12790                String name;
12791                if (opti >= args.length) {
12792                    name = null;
12793                    newArgs = EMPTY_STRING_ARRAY;
12794                } else {
12795                    dumpPackage = args[opti];
12796                    opti++;
12797                    newArgs = new String[args.length - opti];
12798                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12799                            args.length - opti);
12800                }
12801                synchronized (this) {
12802                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12803                }
12804            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12805                String[] newArgs;
12806                String name;
12807                if (opti >= args.length) {
12808                    name = null;
12809                    newArgs = EMPTY_STRING_ARRAY;
12810                } else {
12811                    dumpPackage = args[opti];
12812                    opti++;
12813                    newArgs = new String[args.length - opti];
12814                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12815                            args.length - opti);
12816                }
12817                synchronized (this) {
12818                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12819                }
12820            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12821                synchronized (this) {
12822                    dumpOomLocked(fd, pw, args, opti, true);
12823                }
12824            } else if ("provider".equals(cmd)) {
12825                String[] newArgs;
12826                String name;
12827                if (opti >= args.length) {
12828                    name = null;
12829                    newArgs = EMPTY_STRING_ARRAY;
12830                } else {
12831                    name = args[opti];
12832                    opti++;
12833                    newArgs = new String[args.length - opti];
12834                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12835                }
12836                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12837                    pw.println("No providers match: " + name);
12838                    pw.println("Use -h for help.");
12839                }
12840            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12841                synchronized (this) {
12842                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12843                }
12844            } else if ("service".equals(cmd)) {
12845                String[] newArgs;
12846                String name;
12847                if (opti >= args.length) {
12848                    name = null;
12849                    newArgs = EMPTY_STRING_ARRAY;
12850                } else {
12851                    name = args[opti];
12852                    opti++;
12853                    newArgs = new String[args.length - opti];
12854                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12855                            args.length - opti);
12856                }
12857                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12858                    pw.println("No services match: " + name);
12859                    pw.println("Use -h for help.");
12860                }
12861            } else if ("package".equals(cmd)) {
12862                String[] newArgs;
12863                if (opti >= args.length) {
12864                    pw.println("package: no package name specified");
12865                    pw.println("Use -h for help.");
12866                } else {
12867                    dumpPackage = args[opti];
12868                    opti++;
12869                    newArgs = new String[args.length - opti];
12870                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12871                            args.length - opti);
12872                    args = newArgs;
12873                    opti = 0;
12874                    more = true;
12875                }
12876            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12877                synchronized (this) {
12878                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12879                }
12880            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12881                synchronized (this) {
12882                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12883                }
12884            } else if ("write".equals(cmd)) {
12885                mTaskPersister.flush();
12886                pw.println("All tasks persisted.");
12887                return;
12888            } else if ("track-associations".equals(cmd)) {
12889                synchronized (this) {
12890                    if (!mTrackingAssociations) {
12891                        mTrackingAssociations = true;
12892                        pw.println("Association tracking started.");
12893                    } else {
12894                        pw.println("Association tracking already enabled.");
12895                    }
12896                }
12897                return;
12898            } else if ("untrack-associations".equals(cmd)) {
12899                synchronized (this) {
12900                    if (mTrackingAssociations) {
12901                        mTrackingAssociations = false;
12902                        mAssociations.clear();
12903                        pw.println("Association tracking stopped.");
12904                    } else {
12905                        pw.println("Association tracking not running.");
12906                    }
12907                }
12908                return;
12909            } else {
12910                // Dumping a single activity?
12911                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12912                    pw.println("Bad activity command, or no activities match: " + cmd);
12913                    pw.println("Use -h for help.");
12914                }
12915            }
12916            if (!more) {
12917                Binder.restoreCallingIdentity(origId);
12918                return;
12919            }
12920        }
12921
12922        // No piece of data specified, dump everything.
12923        synchronized (this) {
12924            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12925            pw.println();
12926            if (dumpAll) {
12927                pw.println("-------------------------------------------------------------------------------");
12928            }
12929            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12930            pw.println();
12931            if (dumpAll) {
12932                pw.println("-------------------------------------------------------------------------------");
12933            }
12934            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12935            pw.println();
12936            if (dumpAll) {
12937                pw.println("-------------------------------------------------------------------------------");
12938            }
12939            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12940            pw.println();
12941            if (dumpAll) {
12942                pw.println("-------------------------------------------------------------------------------");
12943            }
12944            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12945            pw.println();
12946            if (dumpAll) {
12947                pw.println("-------------------------------------------------------------------------------");
12948            }
12949            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12950            if (mAssociations.size() > 0) {
12951                pw.println();
12952                if (dumpAll) {
12953                    pw.println("-------------------------------------------------------------------------------");
12954                }
12955                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12956            }
12957            pw.println();
12958            if (dumpAll) {
12959                pw.println("-------------------------------------------------------------------------------");
12960            }
12961            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12962        }
12963        Binder.restoreCallingIdentity(origId);
12964    }
12965
12966    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12967            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12968        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12969
12970        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12971                dumpPackage);
12972        boolean needSep = printedAnything;
12973
12974        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12975                dumpPackage, needSep, "  mFocusedActivity: ");
12976        if (printed) {
12977            printedAnything = true;
12978            needSep = false;
12979        }
12980
12981        if (dumpPackage == null) {
12982            if (needSep) {
12983                pw.println();
12984            }
12985            needSep = true;
12986            printedAnything = true;
12987            mStackSupervisor.dump(pw, "  ");
12988        }
12989
12990        if (!printedAnything) {
12991            pw.println("  (nothing)");
12992        }
12993    }
12994
12995    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12996            int opti, boolean dumpAll, String dumpPackage) {
12997        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12998
12999        boolean printedAnything = false;
13000
13001        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13002            boolean printedHeader = false;
13003
13004            final int N = mRecentTasks.size();
13005            for (int i=0; i<N; i++) {
13006                TaskRecord tr = mRecentTasks.get(i);
13007                if (dumpPackage != null) {
13008                    if (tr.realActivity == null ||
13009                            !dumpPackage.equals(tr.realActivity)) {
13010                        continue;
13011                    }
13012                }
13013                if (!printedHeader) {
13014                    pw.println("  Recent tasks:");
13015                    printedHeader = true;
13016                    printedAnything = true;
13017                }
13018                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13019                        pw.println(tr);
13020                if (dumpAll) {
13021                    mRecentTasks.get(i).dump(pw, "    ");
13022                }
13023            }
13024        }
13025
13026        if (!printedAnything) {
13027            pw.println("  (nothing)");
13028        }
13029    }
13030
13031    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13032            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13033        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13034
13035        int dumpUid = 0;
13036        if (dumpPackage != null) {
13037            IPackageManager pm = AppGlobals.getPackageManager();
13038            try {
13039                dumpUid = pm.getPackageUid(dumpPackage, 0);
13040            } catch (RemoteException e) {
13041            }
13042        }
13043
13044        boolean printedAnything = false;
13045
13046        final long now = SystemClock.uptimeMillis();
13047
13048        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13049            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13050                    = mAssociations.valueAt(i1);
13051            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13052                SparseArray<ArrayMap<String, Association>> sourceUids
13053                        = targetComponents.valueAt(i2);
13054                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13055                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13056                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13057                        Association ass = sourceProcesses.valueAt(i4);
13058                        if (dumpPackage != null) {
13059                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13060                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13061                                continue;
13062                            }
13063                        }
13064                        printedAnything = true;
13065                        pw.print("  ");
13066                        pw.print(ass.mTargetProcess);
13067                        pw.print("/");
13068                        UserHandle.formatUid(pw, ass.mTargetUid);
13069                        pw.print(" <- ");
13070                        pw.print(ass.mSourceProcess);
13071                        pw.print("/");
13072                        UserHandle.formatUid(pw, ass.mSourceUid);
13073                        pw.println();
13074                        pw.print("    via ");
13075                        pw.print(ass.mTargetComponent.flattenToShortString());
13076                        pw.println();
13077                        pw.print("    ");
13078                        long dur = ass.mTime;
13079                        if (ass.mNesting > 0) {
13080                            dur += now - ass.mStartTime;
13081                        }
13082                        TimeUtils.formatDuration(dur, pw);
13083                        pw.print(" (");
13084                        pw.print(ass.mCount);
13085                        pw.println(" times)");
13086                        if (ass.mNesting > 0) {
13087                            pw.print("    ");
13088                            pw.print(" Currently active: ");
13089                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13090                            pw.println();
13091                        }
13092                    }
13093                }
13094            }
13095
13096        }
13097
13098        if (!printedAnything) {
13099            pw.println("  (nothing)");
13100        }
13101    }
13102
13103    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13104            int opti, boolean dumpAll, String dumpPackage) {
13105        boolean needSep = false;
13106        boolean printedAnything = false;
13107        int numPers = 0;
13108
13109        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13110
13111        if (dumpAll) {
13112            final int NP = mProcessNames.getMap().size();
13113            for (int ip=0; ip<NP; ip++) {
13114                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13115                final int NA = procs.size();
13116                for (int ia=0; ia<NA; ia++) {
13117                    ProcessRecord r = procs.valueAt(ia);
13118                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13119                        continue;
13120                    }
13121                    if (!needSep) {
13122                        pw.println("  All known processes:");
13123                        needSep = true;
13124                        printedAnything = true;
13125                    }
13126                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13127                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13128                        pw.print(" "); pw.println(r);
13129                    r.dump(pw, "    ");
13130                    if (r.persistent) {
13131                        numPers++;
13132                    }
13133                }
13134            }
13135        }
13136
13137        if (mIsolatedProcesses.size() > 0) {
13138            boolean printed = false;
13139            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13140                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13141                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13142                    continue;
13143                }
13144                if (!printed) {
13145                    if (needSep) {
13146                        pw.println();
13147                    }
13148                    pw.println("  Isolated process list (sorted by uid):");
13149                    printedAnything = true;
13150                    printed = true;
13151                    needSep = true;
13152                }
13153                pw.println(String.format("%sIsolated #%2d: %s",
13154                        "    ", i, r.toString()));
13155            }
13156        }
13157
13158        if (mActiveUids.size() > 0) {
13159            if (needSep) {
13160                pw.println();
13161            }
13162            pw.println("  UID states:");
13163            for (int i=0; i<mActiveUids.size(); i++) {
13164                UidRecord uidRec = mActiveUids.valueAt(i);
13165                pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13166                pw.print(": "); pw.println(uidRec);
13167            }
13168            needSep = true;
13169            printedAnything = true;
13170        }
13171
13172        if (mLruProcesses.size() > 0) {
13173            if (needSep) {
13174                pw.println();
13175            }
13176            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13177                    pw.print(" total, non-act at ");
13178                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13179                    pw.print(", non-svc at ");
13180                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13181                    pw.println("):");
13182            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13183            needSep = true;
13184            printedAnything = true;
13185        }
13186
13187        if (dumpAll || dumpPackage != null) {
13188            synchronized (mPidsSelfLocked) {
13189                boolean printed = false;
13190                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13191                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13192                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13193                        continue;
13194                    }
13195                    if (!printed) {
13196                        if (needSep) pw.println();
13197                        needSep = true;
13198                        pw.println("  PID mappings:");
13199                        printed = true;
13200                        printedAnything = true;
13201                    }
13202                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13203                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13204                }
13205            }
13206        }
13207
13208        if (mForegroundProcesses.size() > 0) {
13209            synchronized (mPidsSelfLocked) {
13210                boolean printed = false;
13211                for (int i=0; i<mForegroundProcesses.size(); i++) {
13212                    ProcessRecord r = mPidsSelfLocked.get(
13213                            mForegroundProcesses.valueAt(i).pid);
13214                    if (dumpPackage != null && (r == null
13215                            || !r.pkgList.containsKey(dumpPackage))) {
13216                        continue;
13217                    }
13218                    if (!printed) {
13219                        if (needSep) pw.println();
13220                        needSep = true;
13221                        pw.println("  Foreground Processes:");
13222                        printed = true;
13223                        printedAnything = true;
13224                    }
13225                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13226                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13227                }
13228            }
13229        }
13230
13231        if (mPersistentStartingProcesses.size() > 0) {
13232            if (needSep) pw.println();
13233            needSep = true;
13234            printedAnything = true;
13235            pw.println("  Persisent processes that are starting:");
13236            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13237                    "Starting Norm", "Restarting PERS", dumpPackage);
13238        }
13239
13240        if (mRemovedProcesses.size() > 0) {
13241            if (needSep) pw.println();
13242            needSep = true;
13243            printedAnything = true;
13244            pw.println("  Processes that are being removed:");
13245            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13246                    "Removed Norm", "Removed PERS", dumpPackage);
13247        }
13248
13249        if (mProcessesOnHold.size() > 0) {
13250            if (needSep) pw.println();
13251            needSep = true;
13252            printedAnything = true;
13253            pw.println("  Processes that are on old until the system is ready:");
13254            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13255                    "OnHold Norm", "OnHold PERS", dumpPackage);
13256        }
13257
13258        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13259
13260        if (mProcessCrashTimes.getMap().size() > 0) {
13261            boolean printed = false;
13262            long now = SystemClock.uptimeMillis();
13263            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13264            final int NP = pmap.size();
13265            for (int ip=0; ip<NP; ip++) {
13266                String pname = pmap.keyAt(ip);
13267                SparseArray<Long> uids = pmap.valueAt(ip);
13268                final int N = uids.size();
13269                for (int i=0; i<N; i++) {
13270                    int puid = uids.keyAt(i);
13271                    ProcessRecord r = mProcessNames.get(pname, puid);
13272                    if (dumpPackage != null && (r == null
13273                            || !r.pkgList.containsKey(dumpPackage))) {
13274                        continue;
13275                    }
13276                    if (!printed) {
13277                        if (needSep) pw.println();
13278                        needSep = true;
13279                        pw.println("  Time since processes crashed:");
13280                        printed = true;
13281                        printedAnything = true;
13282                    }
13283                    pw.print("    Process "); pw.print(pname);
13284                            pw.print(" uid "); pw.print(puid);
13285                            pw.print(": last crashed ");
13286                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13287                            pw.println(" ago");
13288                }
13289            }
13290        }
13291
13292        if (mBadProcesses.getMap().size() > 0) {
13293            boolean printed = false;
13294            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13295            final int NP = pmap.size();
13296            for (int ip=0; ip<NP; ip++) {
13297                String pname = pmap.keyAt(ip);
13298                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13299                final int N = uids.size();
13300                for (int i=0; i<N; i++) {
13301                    int puid = uids.keyAt(i);
13302                    ProcessRecord r = mProcessNames.get(pname, puid);
13303                    if (dumpPackage != null && (r == null
13304                            || !r.pkgList.containsKey(dumpPackage))) {
13305                        continue;
13306                    }
13307                    if (!printed) {
13308                        if (needSep) pw.println();
13309                        needSep = true;
13310                        pw.println("  Bad processes:");
13311                        printedAnything = true;
13312                    }
13313                    BadProcessInfo info = uids.valueAt(i);
13314                    pw.print("    Bad process "); pw.print(pname);
13315                            pw.print(" uid "); pw.print(puid);
13316                            pw.print(": crashed at time "); pw.println(info.time);
13317                    if (info.shortMsg != null) {
13318                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13319                    }
13320                    if (info.longMsg != null) {
13321                        pw.print("      Long msg: "); pw.println(info.longMsg);
13322                    }
13323                    if (info.stack != null) {
13324                        pw.println("      Stack:");
13325                        int lastPos = 0;
13326                        for (int pos=0; pos<info.stack.length(); pos++) {
13327                            if (info.stack.charAt(pos) == '\n') {
13328                                pw.print("        ");
13329                                pw.write(info.stack, lastPos, pos-lastPos);
13330                                pw.println();
13331                                lastPos = pos+1;
13332                            }
13333                        }
13334                        if (lastPos < info.stack.length()) {
13335                            pw.print("        ");
13336                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13337                            pw.println();
13338                        }
13339                    }
13340                }
13341            }
13342        }
13343
13344        if (dumpPackage == null) {
13345            pw.println();
13346            needSep = false;
13347            pw.println("  mStartedUsers:");
13348            for (int i=0; i<mStartedUsers.size(); i++) {
13349                UserState uss = mStartedUsers.valueAt(i);
13350                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13351                        pw.print(": "); uss.dump("", pw);
13352            }
13353            pw.print("  mStartedUserArray: [");
13354            for (int i=0; i<mStartedUserArray.length; i++) {
13355                if (i > 0) pw.print(", ");
13356                pw.print(mStartedUserArray[i]);
13357            }
13358            pw.println("]");
13359            pw.print("  mUserLru: [");
13360            for (int i=0; i<mUserLru.size(); i++) {
13361                if (i > 0) pw.print(", ");
13362                pw.print(mUserLru.get(i));
13363            }
13364            pw.println("]");
13365            if (dumpAll) {
13366                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13367            }
13368            synchronized (mUserProfileGroupIdsSelfLocked) {
13369                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13370                    pw.println("  mUserProfileGroupIds:");
13371                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13372                        pw.print("    User #");
13373                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13374                        pw.print(" -> profile #");
13375                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13376                    }
13377                }
13378            }
13379        }
13380        if (mHomeProcess != null && (dumpPackage == null
13381                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13382            if (needSep) {
13383                pw.println();
13384                needSep = false;
13385            }
13386            pw.println("  mHomeProcess: " + mHomeProcess);
13387        }
13388        if (mPreviousProcess != null && (dumpPackage == null
13389                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13390            if (needSep) {
13391                pw.println();
13392                needSep = false;
13393            }
13394            pw.println("  mPreviousProcess: " + mPreviousProcess);
13395        }
13396        if (dumpAll) {
13397            StringBuilder sb = new StringBuilder(128);
13398            sb.append("  mPreviousProcessVisibleTime: ");
13399            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13400            pw.println(sb);
13401        }
13402        if (mHeavyWeightProcess != null && (dumpPackage == null
13403                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13404            if (needSep) {
13405                pw.println();
13406                needSep = false;
13407            }
13408            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13409        }
13410        if (dumpPackage == null) {
13411            pw.println("  mConfiguration: " + mConfiguration);
13412        }
13413        if (dumpAll) {
13414            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13415            if (mCompatModePackages.getPackages().size() > 0) {
13416                boolean printed = false;
13417                for (Map.Entry<String, Integer> entry
13418                        : mCompatModePackages.getPackages().entrySet()) {
13419                    String pkg = entry.getKey();
13420                    int mode = entry.getValue();
13421                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13422                        continue;
13423                    }
13424                    if (!printed) {
13425                        pw.println("  mScreenCompatPackages:");
13426                        printed = true;
13427                    }
13428                    pw.print("    "); pw.print(pkg); pw.print(": ");
13429                            pw.print(mode); pw.println();
13430                }
13431            }
13432        }
13433        if (dumpPackage == null) {
13434            pw.println("  mWakefulness="
13435                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13436            pw.println("  mSleepTokens=" + mSleepTokens);
13437            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13438                    + lockScreenShownToString());
13439            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13440            if (mRunningVoice != null) {
13441                pw.println("  mRunningVoice=" + mRunningVoice);
13442                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13443            }
13444        }
13445        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13446                || mOrigWaitForDebugger) {
13447            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13448                    || dumpPackage.equals(mOrigDebugApp)) {
13449                if (needSep) {
13450                    pw.println();
13451                    needSep = false;
13452                }
13453                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13454                        + " mDebugTransient=" + mDebugTransient
13455                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13456            }
13457        }
13458        if (mCurAppTimeTracker != null) {
13459            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13460        }
13461        if (mMemWatchProcesses.getMap().size() > 0) {
13462            pw.println("  Mem watch processes:");
13463            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13464                    = mMemWatchProcesses.getMap();
13465            for (int i=0; i<procs.size(); i++) {
13466                final String proc = procs.keyAt(i);
13467                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13468                for (int j=0; j<uids.size(); j++) {
13469                    if (needSep) {
13470                        pw.println();
13471                        needSep = false;
13472                    }
13473                    StringBuilder sb = new StringBuilder();
13474                    sb.append("    ").append(proc).append('/');
13475                    UserHandle.formatUid(sb, uids.keyAt(j));
13476                    Pair<Long, String> val = uids.valueAt(j);
13477                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13478                    if (val.second != null) {
13479                        sb.append(", report to ").append(val.second);
13480                    }
13481                    pw.println(sb.toString());
13482                }
13483            }
13484            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13485            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13486            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13487                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13488        }
13489        if (mOpenGlTraceApp != null) {
13490            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13491                if (needSep) {
13492                    pw.println();
13493                    needSep = false;
13494                }
13495                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13496            }
13497        }
13498        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13499                || mProfileFd != null) {
13500            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13501                if (needSep) {
13502                    pw.println();
13503                    needSep = false;
13504                }
13505                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13506                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13507                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13508                        + mAutoStopProfiler);
13509                pw.println("  mProfileType=" + mProfileType);
13510            }
13511        }
13512        if (dumpPackage == null) {
13513            if (mAlwaysFinishActivities || mController != null) {
13514                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13515                        + " mController=" + mController);
13516            }
13517            if (dumpAll) {
13518                pw.println("  Total persistent processes: " + numPers);
13519                pw.println("  mProcessesReady=" + mProcessesReady
13520                        + " mSystemReady=" + mSystemReady
13521                        + " mBooted=" + mBooted
13522                        + " mFactoryTest=" + mFactoryTest);
13523                pw.println("  mBooting=" + mBooting
13524                        + " mCallFinishBooting=" + mCallFinishBooting
13525                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13526                pw.print("  mLastPowerCheckRealtime=");
13527                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13528                        pw.println("");
13529                pw.print("  mLastPowerCheckUptime=");
13530                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13531                        pw.println("");
13532                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13533                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13534                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13535                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13536                        + " (" + mLruProcesses.size() + " total)"
13537                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13538                        + " mNumServiceProcs=" + mNumServiceProcs
13539                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13540                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13541                        + " mLastMemoryLevel" + mLastMemoryLevel
13542                        + " mLastNumProcesses" + mLastNumProcesses);
13543                long now = SystemClock.uptimeMillis();
13544                pw.print("  mLastIdleTime=");
13545                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13546                        pw.print(" mLowRamSinceLastIdle=");
13547                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13548                        pw.println();
13549            }
13550        }
13551
13552        if (!printedAnything) {
13553            pw.println("  (nothing)");
13554        }
13555    }
13556
13557    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13558            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13559        if (mProcessesToGc.size() > 0) {
13560            boolean printed = false;
13561            long now = SystemClock.uptimeMillis();
13562            for (int i=0; i<mProcessesToGc.size(); i++) {
13563                ProcessRecord proc = mProcessesToGc.get(i);
13564                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13565                    continue;
13566                }
13567                if (!printed) {
13568                    if (needSep) pw.println();
13569                    needSep = true;
13570                    pw.println("  Processes that are waiting to GC:");
13571                    printed = true;
13572                }
13573                pw.print("    Process "); pw.println(proc);
13574                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13575                        pw.print(", last gced=");
13576                        pw.print(now-proc.lastRequestedGc);
13577                        pw.print(" ms ago, last lowMem=");
13578                        pw.print(now-proc.lastLowMemory);
13579                        pw.println(" ms ago");
13580
13581            }
13582        }
13583        return needSep;
13584    }
13585
13586    void printOomLevel(PrintWriter pw, String name, int adj) {
13587        pw.print("    ");
13588        if (adj >= 0) {
13589            pw.print(' ');
13590            if (adj < 10) pw.print(' ');
13591        } else {
13592            if (adj > -10) pw.print(' ');
13593        }
13594        pw.print(adj);
13595        pw.print(": ");
13596        pw.print(name);
13597        pw.print(" (");
13598        pw.print(mProcessList.getMemLevel(adj)/1024);
13599        pw.println(" kB)");
13600    }
13601
13602    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13603            int opti, boolean dumpAll) {
13604        boolean needSep = false;
13605
13606        if (mLruProcesses.size() > 0) {
13607            if (needSep) pw.println();
13608            needSep = true;
13609            pw.println("  OOM levels:");
13610            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13611            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13612            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13613            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13614            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13615            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13616            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13617            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13618            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13619            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13620            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13621            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13622            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13623            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13624
13625            if (needSep) pw.println();
13626            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13627                    pw.print(" total, non-act at ");
13628                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13629                    pw.print(", non-svc at ");
13630                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13631                    pw.println("):");
13632            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13633            needSep = true;
13634        }
13635
13636        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13637
13638        pw.println();
13639        pw.println("  mHomeProcess: " + mHomeProcess);
13640        pw.println("  mPreviousProcess: " + mPreviousProcess);
13641        if (mHeavyWeightProcess != null) {
13642            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13643        }
13644
13645        return true;
13646    }
13647
13648    /**
13649     * There are three ways to call this:
13650     *  - no provider specified: dump all the providers
13651     *  - a flattened component name that matched an existing provider was specified as the
13652     *    first arg: dump that one provider
13653     *  - the first arg isn't the flattened component name of an existing provider:
13654     *    dump all providers whose component contains the first arg as a substring
13655     */
13656    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13657            int opti, boolean dumpAll) {
13658        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13659    }
13660
13661    static class ItemMatcher {
13662        ArrayList<ComponentName> components;
13663        ArrayList<String> strings;
13664        ArrayList<Integer> objects;
13665        boolean all;
13666
13667        ItemMatcher() {
13668            all = true;
13669        }
13670
13671        void build(String name) {
13672            ComponentName componentName = ComponentName.unflattenFromString(name);
13673            if (componentName != null) {
13674                if (components == null) {
13675                    components = new ArrayList<ComponentName>();
13676                }
13677                components.add(componentName);
13678                all = false;
13679            } else {
13680                int objectId = 0;
13681                // Not a '/' separated full component name; maybe an object ID?
13682                try {
13683                    objectId = Integer.parseInt(name, 16);
13684                    if (objects == null) {
13685                        objects = new ArrayList<Integer>();
13686                    }
13687                    objects.add(objectId);
13688                    all = false;
13689                } catch (RuntimeException e) {
13690                    // Not an integer; just do string match.
13691                    if (strings == null) {
13692                        strings = new ArrayList<String>();
13693                    }
13694                    strings.add(name);
13695                    all = false;
13696                }
13697            }
13698        }
13699
13700        int build(String[] args, int opti) {
13701            for (; opti<args.length; opti++) {
13702                String name = args[opti];
13703                if ("--".equals(name)) {
13704                    return opti+1;
13705                }
13706                build(name);
13707            }
13708            return opti;
13709        }
13710
13711        boolean match(Object object, ComponentName comp) {
13712            if (all) {
13713                return true;
13714            }
13715            if (components != null) {
13716                for (int i=0; i<components.size(); i++) {
13717                    if (components.get(i).equals(comp)) {
13718                        return true;
13719                    }
13720                }
13721            }
13722            if (objects != null) {
13723                for (int i=0; i<objects.size(); i++) {
13724                    if (System.identityHashCode(object) == objects.get(i)) {
13725                        return true;
13726                    }
13727                }
13728            }
13729            if (strings != null) {
13730                String flat = comp.flattenToString();
13731                for (int i=0; i<strings.size(); i++) {
13732                    if (flat.contains(strings.get(i))) {
13733                        return true;
13734                    }
13735                }
13736            }
13737            return false;
13738        }
13739    }
13740
13741    /**
13742     * There are three things that cmd can be:
13743     *  - a flattened component name that matches an existing activity
13744     *  - the cmd arg isn't the flattened component name of an existing activity:
13745     *    dump all activity whose component contains the cmd as a substring
13746     *  - A hex number of the ActivityRecord object instance.
13747     */
13748    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13749            int opti, boolean dumpAll) {
13750        ArrayList<ActivityRecord> activities;
13751
13752        synchronized (this) {
13753            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13754        }
13755
13756        if (activities.size() <= 0) {
13757            return false;
13758        }
13759
13760        String[] newArgs = new String[args.length - opti];
13761        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13762
13763        TaskRecord lastTask = null;
13764        boolean needSep = false;
13765        for (int i=activities.size()-1; i>=0; i--) {
13766            ActivityRecord r = activities.get(i);
13767            if (needSep) {
13768                pw.println();
13769            }
13770            needSep = true;
13771            synchronized (this) {
13772                if (lastTask != r.task) {
13773                    lastTask = r.task;
13774                    pw.print("TASK "); pw.print(lastTask.affinity);
13775                            pw.print(" id="); pw.println(lastTask.taskId);
13776                    if (dumpAll) {
13777                        lastTask.dump(pw, "  ");
13778                    }
13779                }
13780            }
13781            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13782        }
13783        return true;
13784    }
13785
13786    /**
13787     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13788     * there is a thread associated with the activity.
13789     */
13790    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13791            final ActivityRecord r, String[] args, boolean dumpAll) {
13792        String innerPrefix = prefix + "  ";
13793        synchronized (this) {
13794            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13795                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13796                    pw.print(" pid=");
13797                    if (r.app != null) pw.println(r.app.pid);
13798                    else pw.println("(not running)");
13799            if (dumpAll) {
13800                r.dump(pw, innerPrefix);
13801            }
13802        }
13803        if (r.app != null && r.app.thread != null) {
13804            // flush anything that is already in the PrintWriter since the thread is going
13805            // to write to the file descriptor directly
13806            pw.flush();
13807            try {
13808                TransferPipe tp = new TransferPipe();
13809                try {
13810                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13811                            r.appToken, innerPrefix, args);
13812                    tp.go(fd);
13813                } finally {
13814                    tp.kill();
13815                }
13816            } catch (IOException e) {
13817                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13818            } catch (RemoteException e) {
13819                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13820            }
13821        }
13822    }
13823
13824    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13825            int opti, boolean dumpAll, String dumpPackage) {
13826        boolean needSep = false;
13827        boolean onlyHistory = false;
13828        boolean printedAnything = false;
13829
13830        if ("history".equals(dumpPackage)) {
13831            if (opti < args.length && "-s".equals(args[opti])) {
13832                dumpAll = false;
13833            }
13834            onlyHistory = true;
13835            dumpPackage = null;
13836        }
13837
13838        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13839        if (!onlyHistory && dumpAll) {
13840            if (mRegisteredReceivers.size() > 0) {
13841                boolean printed = false;
13842                Iterator it = mRegisteredReceivers.values().iterator();
13843                while (it.hasNext()) {
13844                    ReceiverList r = (ReceiverList)it.next();
13845                    if (dumpPackage != null && (r.app == null ||
13846                            !dumpPackage.equals(r.app.info.packageName))) {
13847                        continue;
13848                    }
13849                    if (!printed) {
13850                        pw.println("  Registered Receivers:");
13851                        needSep = true;
13852                        printed = true;
13853                        printedAnything = true;
13854                    }
13855                    pw.print("  * "); pw.println(r);
13856                    r.dump(pw, "    ");
13857                }
13858            }
13859
13860            if (mReceiverResolver.dump(pw, needSep ?
13861                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13862                    "    ", dumpPackage, false, false)) {
13863                needSep = true;
13864                printedAnything = true;
13865            }
13866        }
13867
13868        for (BroadcastQueue q : mBroadcastQueues) {
13869            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13870            printedAnything |= needSep;
13871        }
13872
13873        needSep = true;
13874
13875        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13876            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13877                if (needSep) {
13878                    pw.println();
13879                }
13880                needSep = true;
13881                printedAnything = true;
13882                pw.print("  Sticky broadcasts for user ");
13883                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13884                StringBuilder sb = new StringBuilder(128);
13885                for (Map.Entry<String, ArrayList<Intent>> ent
13886                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13887                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13888                    if (dumpAll) {
13889                        pw.println(":");
13890                        ArrayList<Intent> intents = ent.getValue();
13891                        final int N = intents.size();
13892                        for (int i=0; i<N; i++) {
13893                            sb.setLength(0);
13894                            sb.append("    Intent: ");
13895                            intents.get(i).toShortString(sb, false, true, false, false);
13896                            pw.println(sb.toString());
13897                            Bundle bundle = intents.get(i).getExtras();
13898                            if (bundle != null) {
13899                                pw.print("      ");
13900                                pw.println(bundle.toString());
13901                            }
13902                        }
13903                    } else {
13904                        pw.println("");
13905                    }
13906                }
13907            }
13908        }
13909
13910        if (!onlyHistory && dumpAll) {
13911            pw.println();
13912            for (BroadcastQueue queue : mBroadcastQueues) {
13913                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13914                        + queue.mBroadcastsScheduled);
13915            }
13916            pw.println("  mHandler:");
13917            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13918            needSep = true;
13919            printedAnything = true;
13920        }
13921
13922        if (!printedAnything) {
13923            pw.println("  (nothing)");
13924        }
13925    }
13926
13927    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13928            int opti, boolean dumpAll, String dumpPackage) {
13929        boolean needSep;
13930        boolean printedAnything = false;
13931
13932        ItemMatcher matcher = new ItemMatcher();
13933        matcher.build(args, opti);
13934
13935        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13936
13937        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13938        printedAnything |= needSep;
13939
13940        if (mLaunchingProviders.size() > 0) {
13941            boolean printed = false;
13942            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13943                ContentProviderRecord r = mLaunchingProviders.get(i);
13944                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13945                    continue;
13946                }
13947                if (!printed) {
13948                    if (needSep) pw.println();
13949                    needSep = true;
13950                    pw.println("  Launching content providers:");
13951                    printed = true;
13952                    printedAnything = true;
13953                }
13954                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13955                        pw.println(r);
13956            }
13957        }
13958
13959        if (mGrantedUriPermissions.size() > 0) {
13960            boolean printed = false;
13961            int dumpUid = -2;
13962            if (dumpPackage != null) {
13963                try {
13964                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13965                } catch (NameNotFoundException e) {
13966                    dumpUid = -1;
13967                }
13968            }
13969            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13970                int uid = mGrantedUriPermissions.keyAt(i);
13971                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13972                    continue;
13973                }
13974                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13975                if (!printed) {
13976                    if (needSep) pw.println();
13977                    needSep = true;
13978                    pw.println("  Granted Uri Permissions:");
13979                    printed = true;
13980                    printedAnything = true;
13981                }
13982                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13983                for (UriPermission perm : perms.values()) {
13984                    pw.print("    "); pw.println(perm);
13985                    if (dumpAll) {
13986                        perm.dump(pw, "      ");
13987                    }
13988                }
13989            }
13990        }
13991
13992        if (!printedAnything) {
13993            pw.println("  (nothing)");
13994        }
13995    }
13996
13997    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13998            int opti, boolean dumpAll, String dumpPackage) {
13999        boolean printed = false;
14000
14001        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14002
14003        if (mIntentSenderRecords.size() > 0) {
14004            Iterator<WeakReference<PendingIntentRecord>> it
14005                    = mIntentSenderRecords.values().iterator();
14006            while (it.hasNext()) {
14007                WeakReference<PendingIntentRecord> ref = it.next();
14008                PendingIntentRecord rec = ref != null ? ref.get(): null;
14009                if (dumpPackage != null && (rec == null
14010                        || !dumpPackage.equals(rec.key.packageName))) {
14011                    continue;
14012                }
14013                printed = true;
14014                if (rec != null) {
14015                    pw.print("  * "); pw.println(rec);
14016                    if (dumpAll) {
14017                        rec.dump(pw, "    ");
14018                    }
14019                } else {
14020                    pw.print("  * "); pw.println(ref);
14021                }
14022            }
14023        }
14024
14025        if (!printed) {
14026            pw.println("  (nothing)");
14027        }
14028    }
14029
14030    private static final int dumpProcessList(PrintWriter pw,
14031            ActivityManagerService service, List list,
14032            String prefix, String normalLabel, String persistentLabel,
14033            String dumpPackage) {
14034        int numPers = 0;
14035        final int N = list.size()-1;
14036        for (int i=N; i>=0; i--) {
14037            ProcessRecord r = (ProcessRecord)list.get(i);
14038            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14039                continue;
14040            }
14041            pw.println(String.format("%s%s #%2d: %s",
14042                    prefix, (r.persistent ? persistentLabel : normalLabel),
14043                    i, r.toString()));
14044            if (r.persistent) {
14045                numPers++;
14046            }
14047        }
14048        return numPers;
14049    }
14050
14051    private static final boolean dumpProcessOomList(PrintWriter pw,
14052            ActivityManagerService service, List<ProcessRecord> origList,
14053            String prefix, String normalLabel, String persistentLabel,
14054            boolean inclDetails, String dumpPackage) {
14055
14056        ArrayList<Pair<ProcessRecord, Integer>> list
14057                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14058        for (int i=0; i<origList.size(); i++) {
14059            ProcessRecord r = origList.get(i);
14060            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14061                continue;
14062            }
14063            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14064        }
14065
14066        if (list.size() <= 0) {
14067            return false;
14068        }
14069
14070        Comparator<Pair<ProcessRecord, Integer>> comparator
14071                = new Comparator<Pair<ProcessRecord, Integer>>() {
14072            @Override
14073            public int compare(Pair<ProcessRecord, Integer> object1,
14074                    Pair<ProcessRecord, Integer> object2) {
14075                if (object1.first.setAdj != object2.first.setAdj) {
14076                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14077                }
14078                if (object1.second.intValue() != object2.second.intValue()) {
14079                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14080                }
14081                return 0;
14082            }
14083        };
14084
14085        Collections.sort(list, comparator);
14086
14087        final long curRealtime = SystemClock.elapsedRealtime();
14088        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14089        final long curUptime = SystemClock.uptimeMillis();
14090        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14091
14092        for (int i=list.size()-1; i>=0; i--) {
14093            ProcessRecord r = list.get(i).first;
14094            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14095            char schedGroup;
14096            switch (r.setSchedGroup) {
14097                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14098                    schedGroup = 'B';
14099                    break;
14100                case Process.THREAD_GROUP_DEFAULT:
14101                    schedGroup = 'F';
14102                    break;
14103                default:
14104                    schedGroup = '?';
14105                    break;
14106            }
14107            char foreground;
14108            if (r.foregroundActivities) {
14109                foreground = 'A';
14110            } else if (r.foregroundServices) {
14111                foreground = 'S';
14112            } else {
14113                foreground = ' ';
14114            }
14115            String procState = ProcessList.makeProcStateString(r.curProcState);
14116            pw.print(prefix);
14117            pw.print(r.persistent ? persistentLabel : normalLabel);
14118            pw.print(" #");
14119            int num = (origList.size()-1)-list.get(i).second;
14120            if (num < 10) pw.print(' ');
14121            pw.print(num);
14122            pw.print(": ");
14123            pw.print(oomAdj);
14124            pw.print(' ');
14125            pw.print(schedGroup);
14126            pw.print('/');
14127            pw.print(foreground);
14128            pw.print('/');
14129            pw.print(procState);
14130            pw.print(" trm:");
14131            if (r.trimMemoryLevel < 10) pw.print(' ');
14132            pw.print(r.trimMemoryLevel);
14133            pw.print(' ');
14134            pw.print(r.toShortString());
14135            pw.print(" (");
14136            pw.print(r.adjType);
14137            pw.println(')');
14138            if (r.adjSource != null || r.adjTarget != null) {
14139                pw.print(prefix);
14140                pw.print("    ");
14141                if (r.adjTarget instanceof ComponentName) {
14142                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14143                } else if (r.adjTarget != null) {
14144                    pw.print(r.adjTarget.toString());
14145                } else {
14146                    pw.print("{null}");
14147                }
14148                pw.print("<=");
14149                if (r.adjSource instanceof ProcessRecord) {
14150                    pw.print("Proc{");
14151                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14152                    pw.println("}");
14153                } else if (r.adjSource != null) {
14154                    pw.println(r.adjSource.toString());
14155                } else {
14156                    pw.println("{null}");
14157                }
14158            }
14159            if (inclDetails) {
14160                pw.print(prefix);
14161                pw.print("    ");
14162                pw.print("oom: max="); pw.print(r.maxAdj);
14163                pw.print(" curRaw="); pw.print(r.curRawAdj);
14164                pw.print(" setRaw="); pw.print(r.setRawAdj);
14165                pw.print(" cur="); pw.print(r.curAdj);
14166                pw.print(" set="); pw.println(r.setAdj);
14167                pw.print(prefix);
14168                pw.print("    ");
14169                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14170                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14171                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14172                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14173                pw.println();
14174                pw.print(prefix);
14175                pw.print("    ");
14176                pw.print("cached="); pw.print(r.cached);
14177                pw.print(" empty="); pw.print(r.empty);
14178                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14179
14180                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14181                    if (r.lastWakeTime != 0) {
14182                        long wtime;
14183                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14184                        synchronized (stats) {
14185                            wtime = stats.getProcessWakeTime(r.info.uid,
14186                                    r.pid, curRealtime);
14187                        }
14188                        long timeUsed = wtime - r.lastWakeTime;
14189                        pw.print(prefix);
14190                        pw.print("    ");
14191                        pw.print("keep awake over ");
14192                        TimeUtils.formatDuration(realtimeSince, pw);
14193                        pw.print(" used ");
14194                        TimeUtils.formatDuration(timeUsed, pw);
14195                        pw.print(" (");
14196                        pw.print((timeUsed*100)/realtimeSince);
14197                        pw.println("%)");
14198                    }
14199                    if (r.lastCpuTime != 0) {
14200                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14201                        pw.print(prefix);
14202                        pw.print("    ");
14203                        pw.print("run cpu over ");
14204                        TimeUtils.formatDuration(uptimeSince, pw);
14205                        pw.print(" used ");
14206                        TimeUtils.formatDuration(timeUsed, pw);
14207                        pw.print(" (");
14208                        pw.print((timeUsed*100)/uptimeSince);
14209                        pw.println("%)");
14210                    }
14211                }
14212            }
14213        }
14214        return true;
14215    }
14216
14217    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14218            String[] args) {
14219        ArrayList<ProcessRecord> procs;
14220        synchronized (this) {
14221            if (args != null && args.length > start
14222                    && args[start].charAt(0) != '-') {
14223                procs = new ArrayList<ProcessRecord>();
14224                int pid = -1;
14225                try {
14226                    pid = Integer.parseInt(args[start]);
14227                } catch (NumberFormatException e) {
14228                }
14229                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14230                    ProcessRecord proc = mLruProcesses.get(i);
14231                    if (proc.pid == pid) {
14232                        procs.add(proc);
14233                    } else if (allPkgs && proc.pkgList != null
14234                            && proc.pkgList.containsKey(args[start])) {
14235                        procs.add(proc);
14236                    } else if (proc.processName.equals(args[start])) {
14237                        procs.add(proc);
14238                    }
14239                }
14240                if (procs.size() <= 0) {
14241                    return null;
14242                }
14243            } else {
14244                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14245            }
14246        }
14247        return procs;
14248    }
14249
14250    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14251            PrintWriter pw, String[] args) {
14252        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14253        if (procs == null) {
14254            pw.println("No process found for: " + args[0]);
14255            return;
14256        }
14257
14258        long uptime = SystemClock.uptimeMillis();
14259        long realtime = SystemClock.elapsedRealtime();
14260        pw.println("Applications Graphics Acceleration Info:");
14261        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14262
14263        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14264            ProcessRecord r = procs.get(i);
14265            if (r.thread != null) {
14266                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14267                pw.flush();
14268                try {
14269                    TransferPipe tp = new TransferPipe();
14270                    try {
14271                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14272                        tp.go(fd);
14273                    } finally {
14274                        tp.kill();
14275                    }
14276                } catch (IOException e) {
14277                    pw.println("Failure while dumping the app: " + r);
14278                    pw.flush();
14279                } catch (RemoteException e) {
14280                    pw.println("Got a RemoteException while dumping the app " + r);
14281                    pw.flush();
14282                }
14283            }
14284        }
14285    }
14286
14287    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14288        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14289        if (procs == null) {
14290            pw.println("No process found for: " + args[0]);
14291            return;
14292        }
14293
14294        pw.println("Applications Database Info:");
14295
14296        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14297            ProcessRecord r = procs.get(i);
14298            if (r.thread != null) {
14299                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14300                pw.flush();
14301                try {
14302                    TransferPipe tp = new TransferPipe();
14303                    try {
14304                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14305                        tp.go(fd);
14306                    } finally {
14307                        tp.kill();
14308                    }
14309                } catch (IOException e) {
14310                    pw.println("Failure while dumping the app: " + r);
14311                    pw.flush();
14312                } catch (RemoteException e) {
14313                    pw.println("Got a RemoteException while dumping the app " + r);
14314                    pw.flush();
14315                }
14316            }
14317        }
14318    }
14319
14320    final static class MemItem {
14321        final boolean isProc;
14322        final String label;
14323        final String shortLabel;
14324        final long pss;
14325        final int id;
14326        final boolean hasActivities;
14327        ArrayList<MemItem> subitems;
14328
14329        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14330                boolean _hasActivities) {
14331            isProc = true;
14332            label = _label;
14333            shortLabel = _shortLabel;
14334            pss = _pss;
14335            id = _id;
14336            hasActivities = _hasActivities;
14337        }
14338
14339        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14340            isProc = false;
14341            label = _label;
14342            shortLabel = _shortLabel;
14343            pss = _pss;
14344            id = _id;
14345            hasActivities = false;
14346        }
14347    }
14348
14349    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14350            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14351        if (sort && !isCompact) {
14352            Collections.sort(items, new Comparator<MemItem>() {
14353                @Override
14354                public int compare(MemItem lhs, MemItem rhs) {
14355                    if (lhs.pss < rhs.pss) {
14356                        return 1;
14357                    } else if (lhs.pss > rhs.pss) {
14358                        return -1;
14359                    }
14360                    return 0;
14361                }
14362            });
14363        }
14364
14365        for (int i=0; i<items.size(); i++) {
14366            MemItem mi = items.get(i);
14367            if (!isCompact) {
14368                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14369            } else if (mi.isProc) {
14370                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14371                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14372                pw.println(mi.hasActivities ? ",a" : ",e");
14373            } else {
14374                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14375                pw.println(mi.pss);
14376            }
14377            if (mi.subitems != null) {
14378                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14379                        true, isCompact);
14380            }
14381        }
14382    }
14383
14384    // These are in KB.
14385    static final long[] DUMP_MEM_BUCKETS = new long[] {
14386        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14387        120*1024, 160*1024, 200*1024,
14388        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14389        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14390    };
14391
14392    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14393            boolean stackLike) {
14394        int start = label.lastIndexOf('.');
14395        if (start >= 0) start++;
14396        else start = 0;
14397        int end = label.length();
14398        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14399            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14400                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14401                out.append(bucket);
14402                out.append(stackLike ? "MB." : "MB ");
14403                out.append(label, start, end);
14404                return;
14405            }
14406        }
14407        out.append(memKB/1024);
14408        out.append(stackLike ? "MB." : "MB ");
14409        out.append(label, start, end);
14410    }
14411
14412    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14413            ProcessList.NATIVE_ADJ,
14414            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14415            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14416            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14417            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14418            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14419            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14420    };
14421    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14422            "Native",
14423            "System", "Persistent", "Persistent Service", "Foreground",
14424            "Visible", "Perceptible",
14425            "Heavy Weight", "Backup",
14426            "A Services", "Home",
14427            "Previous", "B Services", "Cached"
14428    };
14429    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14430            "native",
14431            "sys", "pers", "persvc", "fore",
14432            "vis", "percept",
14433            "heavy", "backup",
14434            "servicea", "home",
14435            "prev", "serviceb", "cached"
14436    };
14437
14438    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14439            long realtime, boolean isCheckinRequest, boolean isCompact) {
14440        if (isCheckinRequest || isCompact) {
14441            // short checkin version
14442            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14443        } else {
14444            pw.println("Applications Memory Usage (kB):");
14445            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14446        }
14447    }
14448
14449    private static final int KSM_SHARED = 0;
14450    private static final int KSM_SHARING = 1;
14451    private static final int KSM_UNSHARED = 2;
14452    private static final int KSM_VOLATILE = 3;
14453
14454    private final long[] getKsmInfo() {
14455        long[] longOut = new long[4];
14456        final int[] SINGLE_LONG_FORMAT = new int[] {
14457            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14458        };
14459        long[] longTmp = new long[1];
14460        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14461                SINGLE_LONG_FORMAT, null, longTmp, null);
14462        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14463        longTmp[0] = 0;
14464        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14465                SINGLE_LONG_FORMAT, null, longTmp, null);
14466        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14467        longTmp[0] = 0;
14468        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14469                SINGLE_LONG_FORMAT, null, longTmp, null);
14470        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14471        longTmp[0] = 0;
14472        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14473                SINGLE_LONG_FORMAT, null, longTmp, null);
14474        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14475        return longOut;
14476    }
14477
14478    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14479            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14480        boolean dumpDetails = false;
14481        boolean dumpFullDetails = false;
14482        boolean dumpDalvik = false;
14483        boolean dumpSummaryOnly = false;
14484        boolean oomOnly = false;
14485        boolean isCompact = false;
14486        boolean localOnly = false;
14487        boolean packages = false;
14488
14489        int opti = 0;
14490        while (opti < args.length) {
14491            String opt = args[opti];
14492            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14493                break;
14494            }
14495            opti++;
14496            if ("-a".equals(opt)) {
14497                dumpDetails = true;
14498                dumpFullDetails = true;
14499                dumpDalvik = true;
14500            } else if ("-d".equals(opt)) {
14501                dumpDalvik = true;
14502            } else if ("-c".equals(opt)) {
14503                isCompact = true;
14504            } else if ("-s".equals(opt)) {
14505                dumpDetails = true;
14506                dumpSummaryOnly = true;
14507            } else if ("--oom".equals(opt)) {
14508                oomOnly = true;
14509            } else if ("--local".equals(opt)) {
14510                localOnly = true;
14511            } else if ("--package".equals(opt)) {
14512                packages = true;
14513            } else if ("-h".equals(opt)) {
14514                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14515                pw.println("  -a: include all available information for each process.");
14516                pw.println("  -d: include dalvik details.");
14517                pw.println("  -c: dump in a compact machine-parseable representation.");
14518                pw.println("  -s: dump only summary of application memory usage.");
14519                pw.println("  --oom: only show processes organized by oom adj.");
14520                pw.println("  --local: only collect details locally, don't call process.");
14521                pw.println("  --package: interpret process arg as package, dumping all");
14522                pw.println("             processes that have loaded that package.");
14523                pw.println("If [process] is specified it can be the name or ");
14524                pw.println("pid of a specific process to dump.");
14525                return;
14526            } else {
14527                pw.println("Unknown argument: " + opt + "; use -h for help");
14528            }
14529        }
14530
14531        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14532        long uptime = SystemClock.uptimeMillis();
14533        long realtime = SystemClock.elapsedRealtime();
14534        final long[] tmpLong = new long[1];
14535
14536        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14537        if (procs == null) {
14538            // No Java processes.  Maybe they want to print a native process.
14539            if (args != null && args.length > opti
14540                    && args[opti].charAt(0) != '-') {
14541                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14542                        = new ArrayList<ProcessCpuTracker.Stats>();
14543                updateCpuStatsNow();
14544                int findPid = -1;
14545                try {
14546                    findPid = Integer.parseInt(args[opti]);
14547                } catch (NumberFormatException e) {
14548                }
14549                synchronized (mProcessCpuTracker) {
14550                    final int N = mProcessCpuTracker.countStats();
14551                    for (int i=0; i<N; i++) {
14552                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14553                        if (st.pid == findPid || (st.baseName != null
14554                                && st.baseName.equals(args[opti]))) {
14555                            nativeProcs.add(st);
14556                        }
14557                    }
14558                }
14559                if (nativeProcs.size() > 0) {
14560                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14561                            isCompact);
14562                    Debug.MemoryInfo mi = null;
14563                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14564                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14565                        final int pid = r.pid;
14566                        if (!isCheckinRequest && dumpDetails) {
14567                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14568                        }
14569                        if (mi == null) {
14570                            mi = new Debug.MemoryInfo();
14571                        }
14572                        if (dumpDetails || (!brief && !oomOnly)) {
14573                            Debug.getMemoryInfo(pid, mi);
14574                        } else {
14575                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14576                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14577                        }
14578                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14579                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14580                        if (isCheckinRequest) {
14581                            pw.println();
14582                        }
14583                    }
14584                    return;
14585                }
14586            }
14587            pw.println("No process found for: " + args[opti]);
14588            return;
14589        }
14590
14591        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14592            dumpDetails = true;
14593        }
14594
14595        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14596
14597        String[] innerArgs = new String[args.length-opti];
14598        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14599
14600        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14601        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14602        long nativePss = 0;
14603        long dalvikPss = 0;
14604        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14605                EmptyArray.LONG;
14606        long otherPss = 0;
14607        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14608
14609        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14610        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14611                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14612
14613        long totalPss = 0;
14614        long cachedPss = 0;
14615
14616        Debug.MemoryInfo mi = null;
14617        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14618            final ProcessRecord r = procs.get(i);
14619            final IApplicationThread thread;
14620            final int pid;
14621            final int oomAdj;
14622            final boolean hasActivities;
14623            synchronized (this) {
14624                thread = r.thread;
14625                pid = r.pid;
14626                oomAdj = r.getSetAdjWithServices();
14627                hasActivities = r.activities.size() > 0;
14628            }
14629            if (thread != null) {
14630                if (!isCheckinRequest && dumpDetails) {
14631                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14632                }
14633                if (mi == null) {
14634                    mi = new Debug.MemoryInfo();
14635                }
14636                if (dumpDetails || (!brief && !oomOnly)) {
14637                    Debug.getMemoryInfo(pid, mi);
14638                } else {
14639                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14640                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14641                }
14642                if (dumpDetails) {
14643                    if (localOnly) {
14644                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14645                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14646                        if (isCheckinRequest) {
14647                            pw.println();
14648                        }
14649                    } else {
14650                        try {
14651                            pw.flush();
14652                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14653                                    dumpDalvik, dumpSummaryOnly, innerArgs);
14654                        } catch (RemoteException e) {
14655                            if (!isCheckinRequest) {
14656                                pw.println("Got RemoteException!");
14657                                pw.flush();
14658                            }
14659                        }
14660                    }
14661                }
14662
14663                final long myTotalPss = mi.getTotalPss();
14664                final long myTotalUss = mi.getTotalUss();
14665
14666                synchronized (this) {
14667                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14668                        // Record this for posterity if the process has been stable.
14669                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14670                    }
14671                }
14672
14673                if (!isCheckinRequest && mi != null) {
14674                    totalPss += myTotalPss;
14675                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14676                            (hasActivities ? " / activities)" : ")"),
14677                            r.processName, myTotalPss, pid, hasActivities);
14678                    procMems.add(pssItem);
14679                    procMemsMap.put(pid, pssItem);
14680
14681                    nativePss += mi.nativePss;
14682                    dalvikPss += mi.dalvikPss;
14683                    for (int j=0; j<dalvikSubitemPss.length; j++) {
14684                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14685                    }
14686                    otherPss += mi.otherPss;
14687                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14688                        long mem = mi.getOtherPss(j);
14689                        miscPss[j] += mem;
14690                        otherPss -= mem;
14691                    }
14692
14693                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14694                        cachedPss += myTotalPss;
14695                    }
14696
14697                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14698                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14699                                || oomIndex == (oomPss.length-1)) {
14700                            oomPss[oomIndex] += myTotalPss;
14701                            if (oomProcs[oomIndex] == null) {
14702                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14703                            }
14704                            oomProcs[oomIndex].add(pssItem);
14705                            break;
14706                        }
14707                    }
14708                }
14709            }
14710        }
14711
14712        long nativeProcTotalPss = 0;
14713
14714        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14715            // If we are showing aggregations, also look for native processes to
14716            // include so that our aggregations are more accurate.
14717            updateCpuStatsNow();
14718            mi = null;
14719            synchronized (mProcessCpuTracker) {
14720                final int N = mProcessCpuTracker.countStats();
14721                for (int i=0; i<N; i++) {
14722                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14723                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14724                        if (mi == null) {
14725                            mi = new Debug.MemoryInfo();
14726                        }
14727                        if (!brief && !oomOnly) {
14728                            Debug.getMemoryInfo(st.pid, mi);
14729                        } else {
14730                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14731                            mi.nativePrivateDirty = (int)tmpLong[0];
14732                        }
14733
14734                        final long myTotalPss = mi.getTotalPss();
14735                        totalPss += myTotalPss;
14736                        nativeProcTotalPss += myTotalPss;
14737
14738                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14739                                st.name, myTotalPss, st.pid, false);
14740                        procMems.add(pssItem);
14741
14742                        nativePss += mi.nativePss;
14743                        dalvikPss += mi.dalvikPss;
14744                        for (int j=0; j<dalvikSubitemPss.length; j++) {
14745                            dalvikSubitemPss[j] += mi.getOtherPss(
14746                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
14747                        }
14748                        otherPss += mi.otherPss;
14749                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14750                            long mem = mi.getOtherPss(j);
14751                            miscPss[j] += mem;
14752                            otherPss -= mem;
14753                        }
14754                        oomPss[0] += myTotalPss;
14755                        if (oomProcs[0] == null) {
14756                            oomProcs[0] = new ArrayList<MemItem>();
14757                        }
14758                        oomProcs[0].add(pssItem);
14759                    }
14760                }
14761            }
14762
14763            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14764
14765            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14766            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14767            if (dalvikSubitemPss.length > 0) {
14768                dalvikItem.subitems = new ArrayList<MemItem>();
14769                for (int j=0; j<dalvikSubitemPss.length; j++) {
14770                    final String name = Debug.MemoryInfo.getOtherLabel(
14771                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
14772                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14773                }
14774            }
14775            catMems.add(dalvikItem);
14776            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14777            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14778                String label = Debug.MemoryInfo.getOtherLabel(j);
14779                catMems.add(new MemItem(label, label, miscPss[j], j));
14780            }
14781
14782            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14783            for (int j=0; j<oomPss.length; j++) {
14784                if (oomPss[j] != 0) {
14785                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14786                            : DUMP_MEM_OOM_LABEL[j];
14787                    MemItem item = new MemItem(label, label, oomPss[j],
14788                            DUMP_MEM_OOM_ADJ[j]);
14789                    item.subitems = oomProcs[j];
14790                    oomMems.add(item);
14791                }
14792            }
14793
14794            if (!brief && !oomOnly && !isCompact) {
14795                pw.println();
14796                pw.println("Total PSS by process:");
14797                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14798                pw.println();
14799            }
14800            if (!isCompact) {
14801                pw.println("Total PSS by OOM adjustment:");
14802            }
14803            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14804            if (!brief && !oomOnly) {
14805                PrintWriter out = categoryPw != null ? categoryPw : pw;
14806                if (!isCompact) {
14807                    out.println();
14808                    out.println("Total PSS by category:");
14809                }
14810                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14811            }
14812            if (!isCompact) {
14813                pw.println();
14814            }
14815            MemInfoReader memInfo = new MemInfoReader();
14816            memInfo.readMemInfo();
14817            if (nativeProcTotalPss > 0) {
14818                synchronized (this) {
14819                    final long cachedKb = memInfo.getCachedSizeKb();
14820                    final long freeKb = memInfo.getFreeSizeKb();
14821                    final long zramKb = memInfo.getZramTotalSizeKb();
14822                    final long kernelKb = memInfo.getKernelUsedSizeKb();
14823                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14824                            kernelKb*1024, nativeProcTotalPss*1024);
14825                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14826                            nativeProcTotalPss);
14827                }
14828            }
14829            if (!brief) {
14830                if (!isCompact) {
14831                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14832                    pw.print(" kB (status ");
14833                    switch (mLastMemoryLevel) {
14834                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14835                            pw.println("normal)");
14836                            break;
14837                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14838                            pw.println("moderate)");
14839                            break;
14840                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14841                            pw.println("low)");
14842                            break;
14843                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14844                            pw.println("critical)");
14845                            break;
14846                        default:
14847                            pw.print(mLastMemoryLevel);
14848                            pw.println(")");
14849                            break;
14850                    }
14851                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14852                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14853                            pw.print(cachedPss); pw.print(" cached pss + ");
14854                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14855                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14856                } else {
14857                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14858                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14859                            + memInfo.getFreeSizeKb()); pw.print(",");
14860                    pw.println(totalPss - cachedPss);
14861                }
14862            }
14863            if (!isCompact) {
14864                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14865                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14866                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14867                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14868                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14869                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14870                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14871            }
14872            if (!brief) {
14873                if (memInfo.getZramTotalSizeKb() != 0) {
14874                    if (!isCompact) {
14875                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14876                                pw.print(" kB physical used for ");
14877                                pw.print(memInfo.getSwapTotalSizeKb()
14878                                        - memInfo.getSwapFreeSizeKb());
14879                                pw.print(" kB in swap (");
14880                                pw.print(memInfo.getSwapTotalSizeKb());
14881                                pw.println(" kB total swap)");
14882                    } else {
14883                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14884                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14885                                pw.println(memInfo.getSwapFreeSizeKb());
14886                    }
14887                }
14888                final long[] ksm = getKsmInfo();
14889                if (!isCompact) {
14890                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14891                            || ksm[KSM_VOLATILE] != 0) {
14892                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14893                                pw.print(" kB saved from shared ");
14894                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14895                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14896                                pw.print(" kB unshared; ");
14897                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14898                    }
14899                    pw.print("   Tuning: ");
14900                    pw.print(ActivityManager.staticGetMemoryClass());
14901                    pw.print(" (large ");
14902                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14903                    pw.print("), oom ");
14904                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14905                    pw.print(" kB");
14906                    pw.print(", restore limit ");
14907                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14908                    pw.print(" kB");
14909                    if (ActivityManager.isLowRamDeviceStatic()) {
14910                        pw.print(" (low-ram)");
14911                    }
14912                    if (ActivityManager.isHighEndGfx()) {
14913                        pw.print(" (high-end-gfx)");
14914                    }
14915                    pw.println();
14916                } else {
14917                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14918                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14919                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14920                    pw.print("tuning,");
14921                    pw.print(ActivityManager.staticGetMemoryClass());
14922                    pw.print(',');
14923                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14924                    pw.print(',');
14925                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14926                    if (ActivityManager.isLowRamDeviceStatic()) {
14927                        pw.print(",low-ram");
14928                    }
14929                    if (ActivityManager.isHighEndGfx()) {
14930                        pw.print(",high-end-gfx");
14931                    }
14932                    pw.println();
14933                }
14934            }
14935        }
14936    }
14937
14938    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14939            long memtrack, String name) {
14940        sb.append("  ");
14941        sb.append(ProcessList.makeOomAdjString(oomAdj));
14942        sb.append(' ');
14943        sb.append(ProcessList.makeProcStateString(procState));
14944        sb.append(' ');
14945        ProcessList.appendRamKb(sb, pss);
14946        sb.append(" kB: ");
14947        sb.append(name);
14948        if (memtrack > 0) {
14949            sb.append(" (");
14950            sb.append(memtrack);
14951            sb.append(" kB memtrack)");
14952        }
14953    }
14954
14955    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14956        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14957        sb.append(" (pid ");
14958        sb.append(mi.pid);
14959        sb.append(") ");
14960        sb.append(mi.adjType);
14961        sb.append('\n');
14962        if (mi.adjReason != null) {
14963            sb.append("                      ");
14964            sb.append(mi.adjReason);
14965            sb.append('\n');
14966        }
14967    }
14968
14969    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14970        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14971        for (int i=0, N=memInfos.size(); i<N; i++) {
14972            ProcessMemInfo mi = memInfos.get(i);
14973            infoMap.put(mi.pid, mi);
14974        }
14975        updateCpuStatsNow();
14976        long[] memtrackTmp = new long[1];
14977        synchronized (mProcessCpuTracker) {
14978            final int N = mProcessCpuTracker.countStats();
14979            for (int i=0; i<N; i++) {
14980                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14981                if (st.vsize > 0) {
14982                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14983                    if (pss > 0) {
14984                        if (infoMap.indexOfKey(st.pid) < 0) {
14985                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14986                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14987                            mi.pss = pss;
14988                            mi.memtrack = memtrackTmp[0];
14989                            memInfos.add(mi);
14990                        }
14991                    }
14992                }
14993            }
14994        }
14995
14996        long totalPss = 0;
14997        long totalMemtrack = 0;
14998        for (int i=0, N=memInfos.size(); i<N; i++) {
14999            ProcessMemInfo mi = memInfos.get(i);
15000            if (mi.pss == 0) {
15001                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15002                mi.memtrack = memtrackTmp[0];
15003            }
15004            totalPss += mi.pss;
15005            totalMemtrack += mi.memtrack;
15006        }
15007        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15008            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15009                if (lhs.oomAdj != rhs.oomAdj) {
15010                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15011                }
15012                if (lhs.pss != rhs.pss) {
15013                    return lhs.pss < rhs.pss ? 1 : -1;
15014                }
15015                return 0;
15016            }
15017        });
15018
15019        StringBuilder tag = new StringBuilder(128);
15020        StringBuilder stack = new StringBuilder(128);
15021        tag.append("Low on memory -- ");
15022        appendMemBucket(tag, totalPss, "total", false);
15023        appendMemBucket(stack, totalPss, "total", true);
15024
15025        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15026        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15027        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15028
15029        boolean firstLine = true;
15030        int lastOomAdj = Integer.MIN_VALUE;
15031        long extraNativeRam = 0;
15032        long extraNativeMemtrack = 0;
15033        long cachedPss = 0;
15034        for (int i=0, N=memInfos.size(); i<N; i++) {
15035            ProcessMemInfo mi = memInfos.get(i);
15036
15037            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15038                cachedPss += mi.pss;
15039            }
15040
15041            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15042                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15043                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15044                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15045                if (lastOomAdj != mi.oomAdj) {
15046                    lastOomAdj = mi.oomAdj;
15047                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15048                        tag.append(" / ");
15049                    }
15050                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15051                        if (firstLine) {
15052                            stack.append(":");
15053                            firstLine = false;
15054                        }
15055                        stack.append("\n\t at ");
15056                    } else {
15057                        stack.append("$");
15058                    }
15059                } else {
15060                    tag.append(" ");
15061                    stack.append("$");
15062                }
15063                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15064                    appendMemBucket(tag, mi.pss, mi.name, false);
15065                }
15066                appendMemBucket(stack, mi.pss, mi.name, true);
15067                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15068                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15069                    stack.append("(");
15070                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15071                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15072                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15073                            stack.append(":");
15074                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15075                        }
15076                    }
15077                    stack.append(")");
15078                }
15079            }
15080
15081            appendMemInfo(fullNativeBuilder, mi);
15082            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15083                // The short form only has native processes that are >= 512K.
15084                if (mi.pss >= 512) {
15085                    appendMemInfo(shortNativeBuilder, mi);
15086                } else {
15087                    extraNativeRam += mi.pss;
15088                    extraNativeMemtrack += mi.memtrack;
15089                }
15090            } else {
15091                // Short form has all other details, but if we have collected RAM
15092                // from smaller native processes let's dump a summary of that.
15093                if (extraNativeRam > 0) {
15094                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15095                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15096                    shortNativeBuilder.append('\n');
15097                    extraNativeRam = 0;
15098                }
15099                appendMemInfo(fullJavaBuilder, mi);
15100            }
15101        }
15102
15103        fullJavaBuilder.append("           ");
15104        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15105        fullJavaBuilder.append(" kB: TOTAL");
15106        if (totalMemtrack > 0) {
15107            fullJavaBuilder.append(" (");
15108            fullJavaBuilder.append(totalMemtrack);
15109            fullJavaBuilder.append(" kB memtrack)");
15110        } else {
15111        }
15112        fullJavaBuilder.append("\n");
15113
15114        MemInfoReader memInfo = new MemInfoReader();
15115        memInfo.readMemInfo();
15116        final long[] infos = memInfo.getRawInfo();
15117
15118        StringBuilder memInfoBuilder = new StringBuilder(1024);
15119        Debug.getMemInfo(infos);
15120        memInfoBuilder.append("  MemInfo: ");
15121        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15122        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15123        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15124        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15125        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15126        memInfoBuilder.append("           ");
15127        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15128        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15129        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15130        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15131        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15132            memInfoBuilder.append("  ZRAM: ");
15133            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15134            memInfoBuilder.append(" kB RAM, ");
15135            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15136            memInfoBuilder.append(" kB swap total, ");
15137            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15138            memInfoBuilder.append(" kB swap free\n");
15139        }
15140        final long[] ksm = getKsmInfo();
15141        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15142                || ksm[KSM_VOLATILE] != 0) {
15143            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15144            memInfoBuilder.append(" kB saved from shared ");
15145            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15146            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15147            memInfoBuilder.append(" kB unshared; ");
15148            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15149        }
15150        memInfoBuilder.append("  Free RAM: ");
15151        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15152                + memInfo.getFreeSizeKb());
15153        memInfoBuilder.append(" kB\n");
15154        memInfoBuilder.append("  Used RAM: ");
15155        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15156        memInfoBuilder.append(" kB\n");
15157        memInfoBuilder.append("  Lost RAM: ");
15158        memInfoBuilder.append(memInfo.getTotalSizeKb()
15159                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15160                - memInfo.getKernelUsedSizeKb());
15161        memInfoBuilder.append(" kB\n");
15162        Slog.i(TAG, "Low on memory:");
15163        Slog.i(TAG, shortNativeBuilder.toString());
15164        Slog.i(TAG, fullJavaBuilder.toString());
15165        Slog.i(TAG, memInfoBuilder.toString());
15166
15167        StringBuilder dropBuilder = new StringBuilder(1024);
15168        /*
15169        StringWriter oomSw = new StringWriter();
15170        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15171        StringWriter catSw = new StringWriter();
15172        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15173        String[] emptyArgs = new String[] { };
15174        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15175        oomPw.flush();
15176        String oomString = oomSw.toString();
15177        */
15178        dropBuilder.append("Low on memory:");
15179        dropBuilder.append(stack);
15180        dropBuilder.append('\n');
15181        dropBuilder.append(fullNativeBuilder);
15182        dropBuilder.append(fullJavaBuilder);
15183        dropBuilder.append('\n');
15184        dropBuilder.append(memInfoBuilder);
15185        dropBuilder.append('\n');
15186        /*
15187        dropBuilder.append(oomString);
15188        dropBuilder.append('\n');
15189        */
15190        StringWriter catSw = new StringWriter();
15191        synchronized (ActivityManagerService.this) {
15192            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15193            String[] emptyArgs = new String[] { };
15194            catPw.println();
15195            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15196            catPw.println();
15197            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15198                    false, false, null);
15199            catPw.println();
15200            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15201            catPw.flush();
15202        }
15203        dropBuilder.append(catSw.toString());
15204        addErrorToDropBox("lowmem", null, "system_server", null,
15205                null, tag.toString(), dropBuilder.toString(), null, null);
15206        //Slog.i(TAG, "Sent to dropbox:");
15207        //Slog.i(TAG, dropBuilder.toString());
15208        synchronized (ActivityManagerService.this) {
15209            long now = SystemClock.uptimeMillis();
15210            if (mLastMemUsageReportTime < now) {
15211                mLastMemUsageReportTime = now;
15212            }
15213        }
15214    }
15215
15216    /**
15217     * Searches array of arguments for the specified string
15218     * @param args array of argument strings
15219     * @param value value to search for
15220     * @return true if the value is contained in the array
15221     */
15222    private static boolean scanArgs(String[] args, String value) {
15223        if (args != null) {
15224            for (String arg : args) {
15225                if (value.equals(arg)) {
15226                    return true;
15227                }
15228            }
15229        }
15230        return false;
15231    }
15232
15233    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15234            ContentProviderRecord cpr, boolean always) {
15235        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15236
15237        if (!inLaunching || always) {
15238            synchronized (cpr) {
15239                cpr.launchingApp = null;
15240                cpr.notifyAll();
15241            }
15242            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15243            String names[] = cpr.info.authority.split(";");
15244            for (int j = 0; j < names.length; j++) {
15245                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15246            }
15247        }
15248
15249        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15250            ContentProviderConnection conn = cpr.connections.get(i);
15251            if (conn.waiting) {
15252                // If this connection is waiting for the provider, then we don't
15253                // need to mess with its process unless we are always removing
15254                // or for some reason the provider is not currently launching.
15255                if (inLaunching && !always) {
15256                    continue;
15257                }
15258            }
15259            ProcessRecord capp = conn.client;
15260            conn.dead = true;
15261            if (conn.stableCount > 0) {
15262                if (!capp.persistent && capp.thread != null
15263                        && capp.pid != 0
15264                        && capp.pid != MY_PID) {
15265                    capp.kill("depends on provider "
15266                            + cpr.name.flattenToShortString()
15267                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15268                }
15269            } else if (capp.thread != null && conn.provider.provider != null) {
15270                try {
15271                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15272                } catch (RemoteException e) {
15273                }
15274                // In the protocol here, we don't expect the client to correctly
15275                // clean up this connection, we'll just remove it.
15276                cpr.connections.remove(i);
15277                if (conn.client.conProviders.remove(conn)) {
15278                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15279                }
15280            }
15281        }
15282
15283        if (inLaunching && always) {
15284            mLaunchingProviders.remove(cpr);
15285        }
15286        return inLaunching;
15287    }
15288
15289    /**
15290     * Main code for cleaning up a process when it has gone away.  This is
15291     * called both as a result of the process dying, or directly when stopping
15292     * a process when running in single process mode.
15293     *
15294     * @return Returns true if the given process has been restarted, so the
15295     * app that was passed in must remain on the process lists.
15296     */
15297    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15298            boolean restarting, boolean allowRestart, int index) {
15299        if (index >= 0) {
15300            removeLruProcessLocked(app);
15301            ProcessList.remove(app.pid);
15302        }
15303
15304        mProcessesToGc.remove(app);
15305        mPendingPssProcesses.remove(app);
15306
15307        // Dismiss any open dialogs.
15308        if (app.crashDialog != null && !app.forceCrashReport) {
15309            app.crashDialog.dismiss();
15310            app.crashDialog = null;
15311        }
15312        if (app.anrDialog != null) {
15313            app.anrDialog.dismiss();
15314            app.anrDialog = null;
15315        }
15316        if (app.waitDialog != null) {
15317            app.waitDialog.dismiss();
15318            app.waitDialog = null;
15319        }
15320
15321        app.crashing = false;
15322        app.notResponding = false;
15323
15324        app.resetPackageList(mProcessStats);
15325        app.unlinkDeathRecipient();
15326        app.makeInactive(mProcessStats);
15327        app.waitingToKill = null;
15328        app.forcingToForeground = null;
15329        updateProcessForegroundLocked(app, false, false);
15330        app.foregroundActivities = false;
15331        app.hasShownUi = false;
15332        app.treatLikeActivity = false;
15333        app.hasAboveClient = false;
15334        app.hasClientActivities = false;
15335
15336        mServices.killServicesLocked(app, allowRestart);
15337
15338        boolean restart = false;
15339
15340        // Remove published content providers.
15341        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15342            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15343            final boolean always = app.bad || !allowRestart;
15344            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15345            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15346                // We left the provider in the launching list, need to
15347                // restart it.
15348                restart = true;
15349            }
15350
15351            cpr.provider = null;
15352            cpr.proc = null;
15353        }
15354        app.pubProviders.clear();
15355
15356        // Take care of any launching providers waiting for this process.
15357        if (checkAppInLaunchingProvidersLocked(app, false)) {
15358            restart = true;
15359        }
15360
15361        // Unregister from connected content providers.
15362        if (!app.conProviders.isEmpty()) {
15363            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15364                ContentProviderConnection conn = app.conProviders.get(i);
15365                conn.provider.connections.remove(conn);
15366                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15367                        conn.provider.name);
15368            }
15369            app.conProviders.clear();
15370        }
15371
15372        // At this point there may be remaining entries in mLaunchingProviders
15373        // where we were the only one waiting, so they are no longer of use.
15374        // Look for these and clean up if found.
15375        // XXX Commented out for now.  Trying to figure out a way to reproduce
15376        // the actual situation to identify what is actually going on.
15377        if (false) {
15378            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15379                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15380                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15381                    synchronized (cpr) {
15382                        cpr.launchingApp = null;
15383                        cpr.notifyAll();
15384                    }
15385                }
15386            }
15387        }
15388
15389        skipCurrentReceiverLocked(app);
15390
15391        // Unregister any receivers.
15392        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15393            removeReceiverLocked(app.receivers.valueAt(i));
15394        }
15395        app.receivers.clear();
15396
15397        // If the app is undergoing backup, tell the backup manager about it
15398        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15399            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15400                    + mBackupTarget.appInfo + " died during backup");
15401            try {
15402                IBackupManager bm = IBackupManager.Stub.asInterface(
15403                        ServiceManager.getService(Context.BACKUP_SERVICE));
15404                bm.agentDisconnected(app.info.packageName);
15405            } catch (RemoteException e) {
15406                // can't happen; backup manager is local
15407            }
15408        }
15409
15410        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15411            ProcessChangeItem item = mPendingProcessChanges.get(i);
15412            if (item.pid == app.pid) {
15413                mPendingProcessChanges.remove(i);
15414                mAvailProcessChanges.add(item);
15415            }
15416        }
15417        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15418
15419        // If the caller is restarting this app, then leave it in its
15420        // current lists and let the caller take care of it.
15421        if (restarting) {
15422            return false;
15423        }
15424
15425        if (!app.persistent || app.isolated) {
15426            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15427                    "Removing non-persistent process during cleanup: " + app);
15428            removeProcessNameLocked(app.processName, app.uid);
15429            if (mHeavyWeightProcess == app) {
15430                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15431                        mHeavyWeightProcess.userId, 0));
15432                mHeavyWeightProcess = null;
15433            }
15434        } else if (!app.removed) {
15435            // This app is persistent, so we need to keep its record around.
15436            // If it is not already on the pending app list, add it there
15437            // and start a new process for it.
15438            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15439                mPersistentStartingProcesses.add(app);
15440                restart = true;
15441            }
15442        }
15443        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15444                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15445        mProcessesOnHold.remove(app);
15446
15447        if (app == mHomeProcess) {
15448            mHomeProcess = null;
15449        }
15450        if (app == mPreviousProcess) {
15451            mPreviousProcess = null;
15452        }
15453
15454        if (restart && !app.isolated) {
15455            // We have components that still need to be running in the
15456            // process, so re-launch it.
15457            if (index < 0) {
15458                ProcessList.remove(app.pid);
15459            }
15460            addProcessNameLocked(app);
15461            startProcessLocked(app, "restart", app.processName);
15462            return true;
15463        } else if (app.pid > 0 && app.pid != MY_PID) {
15464            // Goodbye!
15465            boolean removed;
15466            synchronized (mPidsSelfLocked) {
15467                mPidsSelfLocked.remove(app.pid);
15468                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15469            }
15470            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15471            if (app.isolated) {
15472                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15473            }
15474            app.setPid(0);
15475        }
15476        return false;
15477    }
15478
15479    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15480        // Look through the content providers we are waiting to have launched,
15481        // and if any run in this process then either schedule a restart of
15482        // the process or kill the client waiting for it if this process has
15483        // gone bad.
15484        boolean restart = false;
15485        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15486            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15487            if (cpr.launchingApp == app) {
15488                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15489                    restart = true;
15490                } else {
15491                    removeDyingProviderLocked(app, cpr, true);
15492                }
15493            }
15494        }
15495        return restart;
15496    }
15497
15498    // =========================================================
15499    // SERVICES
15500    // =========================================================
15501
15502    @Override
15503    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15504            int flags) {
15505        enforceNotIsolatedCaller("getServices");
15506        synchronized (this) {
15507            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15508        }
15509    }
15510
15511    @Override
15512    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15513        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15514        synchronized (this) {
15515            return mServices.getRunningServiceControlPanelLocked(name);
15516        }
15517    }
15518
15519    @Override
15520    public ComponentName startService(IApplicationThread caller, Intent service,
15521            String resolvedType, int userId) throws TransactionTooLargeException {
15522        enforceNotIsolatedCaller("startService");
15523        // Refuse possible leaked file descriptors
15524        if (service != null && service.hasFileDescriptors() == true) {
15525            throw new IllegalArgumentException("File descriptors passed in Intent");
15526        }
15527
15528        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15529                "startService: " + service + " type=" + resolvedType);
15530        synchronized(this) {
15531            final int callingPid = Binder.getCallingPid();
15532            final int callingUid = Binder.getCallingUid();
15533            final long origId = Binder.clearCallingIdentity();
15534            ComponentName res = mServices.startServiceLocked(caller, service,
15535                    resolvedType, callingPid, callingUid, userId);
15536            Binder.restoreCallingIdentity(origId);
15537            return res;
15538        }
15539    }
15540
15541    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, int userId)
15542            throws TransactionTooLargeException {
15543        synchronized(this) {
15544            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15545                    "startServiceInPackage: " + service + " type=" + resolvedType);
15546            final long origId = Binder.clearCallingIdentity();
15547            ComponentName res = mServices.startServiceLocked(null, service,
15548                    resolvedType, -1, uid, userId);
15549            Binder.restoreCallingIdentity(origId);
15550            return res;
15551        }
15552    }
15553
15554    @Override
15555    public int stopService(IApplicationThread caller, Intent service,
15556            String resolvedType, int userId) {
15557        enforceNotIsolatedCaller("stopService");
15558        // Refuse possible leaked file descriptors
15559        if (service != null && service.hasFileDescriptors() == true) {
15560            throw new IllegalArgumentException("File descriptors passed in Intent");
15561        }
15562
15563        synchronized(this) {
15564            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15565        }
15566    }
15567
15568    @Override
15569    public IBinder peekService(Intent service, String resolvedType) {
15570        enforceNotIsolatedCaller("peekService");
15571        // Refuse possible leaked file descriptors
15572        if (service != null && service.hasFileDescriptors() == true) {
15573            throw new IllegalArgumentException("File descriptors passed in Intent");
15574        }
15575        synchronized(this) {
15576            return mServices.peekServiceLocked(service, resolvedType);
15577        }
15578    }
15579
15580    @Override
15581    public boolean stopServiceToken(ComponentName className, IBinder token,
15582            int startId) {
15583        synchronized(this) {
15584            return mServices.stopServiceTokenLocked(className, token, startId);
15585        }
15586    }
15587
15588    @Override
15589    public void setServiceForeground(ComponentName className, IBinder token,
15590            int id, Notification notification, boolean removeNotification) {
15591        synchronized(this) {
15592            mServices.setServiceForegroundLocked(className, token, id, notification,
15593                    removeNotification);
15594        }
15595    }
15596
15597    @Override
15598    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15599            boolean requireFull, String name, String callerPackage) {
15600        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15601                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15602    }
15603
15604    int unsafeConvertIncomingUser(int userId) {
15605        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15606                ? mCurrentUserId : userId;
15607    }
15608
15609    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15610            int allowMode, String name, String callerPackage) {
15611        final int callingUserId = UserHandle.getUserId(callingUid);
15612        if (callingUserId == userId) {
15613            return userId;
15614        }
15615
15616        // Note that we may be accessing mCurrentUserId outside of a lock...
15617        // shouldn't be a big deal, if this is being called outside
15618        // of a locked context there is intrinsically a race with
15619        // the value the caller will receive and someone else changing it.
15620        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15621        // we will switch to the calling user if access to the current user fails.
15622        int targetUserId = unsafeConvertIncomingUser(userId);
15623
15624        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15625            final boolean allow;
15626            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15627                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15628                // If the caller has this permission, they always pass go.  And collect $200.
15629                allow = true;
15630            } else if (allowMode == ALLOW_FULL_ONLY) {
15631                // We require full access, sucks to be you.
15632                allow = false;
15633            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15634                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15635                // If the caller does not have either permission, they are always doomed.
15636                allow = false;
15637            } else if (allowMode == ALLOW_NON_FULL) {
15638                // We are blanket allowing non-full access, you lucky caller!
15639                allow = true;
15640            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15641                // We may or may not allow this depending on whether the two users are
15642                // in the same profile.
15643                synchronized (mUserProfileGroupIdsSelfLocked) {
15644                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15645                            UserInfo.NO_PROFILE_GROUP_ID);
15646                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15647                            UserInfo.NO_PROFILE_GROUP_ID);
15648                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15649                            && callingProfile == targetProfile;
15650                }
15651            } else {
15652                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15653            }
15654            if (!allow) {
15655                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15656                    // In this case, they would like to just execute as their
15657                    // owner user instead of failing.
15658                    targetUserId = callingUserId;
15659                } else {
15660                    StringBuilder builder = new StringBuilder(128);
15661                    builder.append("Permission Denial: ");
15662                    builder.append(name);
15663                    if (callerPackage != null) {
15664                        builder.append(" from ");
15665                        builder.append(callerPackage);
15666                    }
15667                    builder.append(" asks to run as user ");
15668                    builder.append(userId);
15669                    builder.append(" but is calling from user ");
15670                    builder.append(UserHandle.getUserId(callingUid));
15671                    builder.append("; this requires ");
15672                    builder.append(INTERACT_ACROSS_USERS_FULL);
15673                    if (allowMode != ALLOW_FULL_ONLY) {
15674                        builder.append(" or ");
15675                        builder.append(INTERACT_ACROSS_USERS);
15676                    }
15677                    String msg = builder.toString();
15678                    Slog.w(TAG, msg);
15679                    throw new SecurityException(msg);
15680                }
15681            }
15682        }
15683        if (!allowAll && targetUserId < 0) {
15684            throw new IllegalArgumentException(
15685                    "Call does not support special user #" + targetUserId);
15686        }
15687        // Check shell permission
15688        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15689            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15690                    targetUserId)) {
15691                throw new SecurityException("Shell does not have permission to access user "
15692                        + targetUserId + "\n " + Debug.getCallers(3));
15693            }
15694        }
15695        return targetUserId;
15696    }
15697
15698    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15699            String className, int flags) {
15700        boolean result = false;
15701        // For apps that don't have pre-defined UIDs, check for permission
15702        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15703            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15704                if (ActivityManager.checkUidPermission(
15705                        INTERACT_ACROSS_USERS,
15706                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15707                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15708                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15709                            + " requests FLAG_SINGLE_USER, but app does not hold "
15710                            + INTERACT_ACROSS_USERS;
15711                    Slog.w(TAG, msg);
15712                    throw new SecurityException(msg);
15713                }
15714                // Permission passed
15715                result = true;
15716            }
15717        } else if ("system".equals(componentProcessName)) {
15718            result = true;
15719        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15720            // Phone app and persistent apps are allowed to export singleuser providers.
15721            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15722                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15723        }
15724        if (DEBUG_MU) Slog.v(TAG_MU,
15725                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15726                + Integer.toHexString(flags) + ") = " + result);
15727        return result;
15728    }
15729
15730    /**
15731     * Checks to see if the caller is in the same app as the singleton
15732     * component, or the component is in a special app. It allows special apps
15733     * to export singleton components but prevents exporting singleton
15734     * components for regular apps.
15735     */
15736    boolean isValidSingletonCall(int callingUid, int componentUid) {
15737        int componentAppId = UserHandle.getAppId(componentUid);
15738        return UserHandle.isSameApp(callingUid, componentUid)
15739                || componentAppId == Process.SYSTEM_UID
15740                || componentAppId == Process.PHONE_UID
15741                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15742                        == PackageManager.PERMISSION_GRANTED;
15743    }
15744
15745    public int bindService(IApplicationThread caller, IBinder token, Intent service,
15746            String resolvedType, IServiceConnection connection, int flags, int userId)
15747            throws TransactionTooLargeException {
15748        enforceNotIsolatedCaller("bindService");
15749
15750        // Refuse possible leaked file descriptors
15751        if (service != null && service.hasFileDescriptors() == true) {
15752            throw new IllegalArgumentException("File descriptors passed in Intent");
15753        }
15754
15755        synchronized(this) {
15756            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15757                    connection, flags, userId);
15758        }
15759    }
15760
15761    public boolean unbindService(IServiceConnection connection) {
15762        synchronized (this) {
15763            return mServices.unbindServiceLocked(connection);
15764        }
15765    }
15766
15767    public void publishService(IBinder token, Intent intent, IBinder service) {
15768        // Refuse possible leaked file descriptors
15769        if (intent != null && intent.hasFileDescriptors() == true) {
15770            throw new IllegalArgumentException("File descriptors passed in Intent");
15771        }
15772
15773        synchronized(this) {
15774            if (!(token instanceof ServiceRecord)) {
15775                throw new IllegalArgumentException("Invalid service token");
15776            }
15777            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15778        }
15779    }
15780
15781    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15782        // Refuse possible leaked file descriptors
15783        if (intent != null && intent.hasFileDescriptors() == true) {
15784            throw new IllegalArgumentException("File descriptors passed in Intent");
15785        }
15786
15787        synchronized(this) {
15788            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15789        }
15790    }
15791
15792    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15793        synchronized(this) {
15794            if (!(token instanceof ServiceRecord)) {
15795                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15796                throw new IllegalArgumentException("Invalid service token");
15797            }
15798            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15799        }
15800    }
15801
15802    // =========================================================
15803    // BACKUP AND RESTORE
15804    // =========================================================
15805
15806    // Cause the target app to be launched if necessary and its backup agent
15807    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15808    // activity manager to announce its creation.
15809    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15810        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15811                "bindBackupAgent: app=" + app + " mode=" + backupMode);
15812        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15813
15814        synchronized(this) {
15815            // !!! TODO: currently no check here that we're already bound
15816            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15817            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15818            synchronized (stats) {
15819                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15820            }
15821
15822            // Backup agent is now in use, its package can't be stopped.
15823            try {
15824                AppGlobals.getPackageManager().setPackageStoppedState(
15825                        app.packageName, false, UserHandle.getUserId(app.uid));
15826            } catch (RemoteException e) {
15827            } catch (IllegalArgumentException e) {
15828                Slog.w(TAG, "Failed trying to unstop package "
15829                        + app.packageName + ": " + e);
15830            }
15831
15832            BackupRecord r = new BackupRecord(ss, app, backupMode);
15833            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15834                    ? new ComponentName(app.packageName, app.backupAgentName)
15835                    : new ComponentName("android", "FullBackupAgent");
15836            // startProcessLocked() returns existing proc's record if it's already running
15837            ProcessRecord proc = startProcessLocked(app.processName, app,
15838                    false, 0, "backup", hostingName, false, false, false);
15839            if (proc == null) {
15840                Slog.e(TAG, "Unable to start backup agent process " + r);
15841                return false;
15842            }
15843
15844            r.app = proc;
15845            mBackupTarget = r;
15846            mBackupAppName = app.packageName;
15847
15848            // Try not to kill the process during backup
15849            updateOomAdjLocked(proc);
15850
15851            // If the process is already attached, schedule the creation of the backup agent now.
15852            // If it is not yet live, this will be done when it attaches to the framework.
15853            if (proc.thread != null) {
15854                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
15855                try {
15856                    proc.thread.scheduleCreateBackupAgent(app,
15857                            compatibilityInfoForPackageLocked(app), backupMode);
15858                } catch (RemoteException e) {
15859                    // Will time out on the backup manager side
15860                }
15861            } else {
15862                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
15863            }
15864            // Invariants: at this point, the target app process exists and the application
15865            // is either already running or in the process of coming up.  mBackupTarget and
15866            // mBackupAppName describe the app, so that when it binds back to the AM we
15867            // know that it's scheduled for a backup-agent operation.
15868        }
15869
15870        return true;
15871    }
15872
15873    @Override
15874    public void clearPendingBackup() {
15875        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
15876        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15877
15878        synchronized (this) {
15879            mBackupTarget = null;
15880            mBackupAppName = null;
15881        }
15882    }
15883
15884    // A backup agent has just come up
15885    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15886        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
15887                + " = " + agent);
15888
15889        synchronized(this) {
15890            if (!agentPackageName.equals(mBackupAppName)) {
15891                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15892                return;
15893            }
15894        }
15895
15896        long oldIdent = Binder.clearCallingIdentity();
15897        try {
15898            IBackupManager bm = IBackupManager.Stub.asInterface(
15899                    ServiceManager.getService(Context.BACKUP_SERVICE));
15900            bm.agentConnected(agentPackageName, agent);
15901        } catch (RemoteException e) {
15902            // can't happen; the backup manager service is local
15903        } catch (Exception e) {
15904            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15905            e.printStackTrace();
15906        } finally {
15907            Binder.restoreCallingIdentity(oldIdent);
15908        }
15909    }
15910
15911    // done with this agent
15912    public void unbindBackupAgent(ApplicationInfo appInfo) {
15913        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
15914        if (appInfo == null) {
15915            Slog.w(TAG, "unbind backup agent for null app");
15916            return;
15917        }
15918
15919        synchronized(this) {
15920            try {
15921                if (mBackupAppName == null) {
15922                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15923                    return;
15924                }
15925
15926                if (!mBackupAppName.equals(appInfo.packageName)) {
15927                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15928                    return;
15929                }
15930
15931                // Not backing this app up any more; reset its OOM adjustment
15932                final ProcessRecord proc = mBackupTarget.app;
15933                updateOomAdjLocked(proc);
15934
15935                // If the app crashed during backup, 'thread' will be null here
15936                if (proc.thread != null) {
15937                    try {
15938                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15939                                compatibilityInfoForPackageLocked(appInfo));
15940                    } catch (Exception e) {
15941                        Slog.e(TAG, "Exception when unbinding backup agent:");
15942                        e.printStackTrace();
15943                    }
15944                }
15945            } finally {
15946                mBackupTarget = null;
15947                mBackupAppName = null;
15948            }
15949        }
15950    }
15951    // =========================================================
15952    // BROADCASTS
15953    // =========================================================
15954
15955    boolean isPendingBroadcastProcessLocked(int pid) {
15956        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15957                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15958    }
15959
15960    void skipPendingBroadcastLocked(int pid) {
15961            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15962            for (BroadcastQueue queue : mBroadcastQueues) {
15963                queue.skipPendingBroadcastLocked(pid);
15964            }
15965    }
15966
15967    // The app just attached; send any pending broadcasts that it should receive
15968    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15969        boolean didSomething = false;
15970        for (BroadcastQueue queue : mBroadcastQueues) {
15971            didSomething |= queue.sendPendingBroadcastsLocked(app);
15972        }
15973        return didSomething;
15974    }
15975
15976    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15977            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15978        enforceNotIsolatedCaller("registerReceiver");
15979        ArrayList<Intent> stickyIntents = null;
15980        ProcessRecord callerApp = null;
15981        int callingUid;
15982        int callingPid;
15983        synchronized(this) {
15984            if (caller != null) {
15985                callerApp = getRecordForAppLocked(caller);
15986                if (callerApp == null) {
15987                    throw new SecurityException(
15988                            "Unable to find app for caller " + caller
15989                            + " (pid=" + Binder.getCallingPid()
15990                            + ") when registering receiver " + receiver);
15991                }
15992                if (callerApp.info.uid != Process.SYSTEM_UID &&
15993                        !callerApp.pkgList.containsKey(callerPackage) &&
15994                        !"android".equals(callerPackage)) {
15995                    throw new SecurityException("Given caller package " + callerPackage
15996                            + " is not running in process " + callerApp);
15997                }
15998                callingUid = callerApp.info.uid;
15999                callingPid = callerApp.pid;
16000            } else {
16001                callerPackage = null;
16002                callingUid = Binder.getCallingUid();
16003                callingPid = Binder.getCallingPid();
16004            }
16005
16006            userId = handleIncomingUser(callingPid, callingUid, userId,
16007                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16008
16009            Iterator<String> actions = filter.actionsIterator();
16010            if (actions == null) {
16011                ArrayList<String> noAction = new ArrayList<String>(1);
16012                noAction.add(null);
16013                actions = noAction.iterator();
16014            }
16015
16016            // Collect stickies of users
16017            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16018            while (actions.hasNext()) {
16019                String action = actions.next();
16020                for (int id : userIds) {
16021                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16022                    if (stickies != null) {
16023                        ArrayList<Intent> intents = stickies.get(action);
16024                        if (intents != null) {
16025                            if (stickyIntents == null) {
16026                                stickyIntents = new ArrayList<Intent>();
16027                            }
16028                            stickyIntents.addAll(intents);
16029                        }
16030                    }
16031                }
16032            }
16033        }
16034
16035        ArrayList<Intent> allSticky = null;
16036        if (stickyIntents != null) {
16037            final ContentResolver resolver = mContext.getContentResolver();
16038            // Look for any matching sticky broadcasts...
16039            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16040                Intent intent = stickyIntents.get(i);
16041                // If intent has scheme "content", it will need to acccess
16042                // provider that needs to lock mProviderMap in ActivityThread
16043                // and also it may need to wait application response, so we
16044                // cannot lock ActivityManagerService here.
16045                if (filter.match(resolver, intent, true, TAG) >= 0) {
16046                    if (allSticky == null) {
16047                        allSticky = new ArrayList<Intent>();
16048                    }
16049                    allSticky.add(intent);
16050                }
16051            }
16052        }
16053
16054        // The first sticky in the list is returned directly back to the client.
16055        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16056        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16057        if (receiver == null) {
16058            return sticky;
16059        }
16060
16061        synchronized (this) {
16062            if (callerApp != null && (callerApp.thread == null
16063                    || callerApp.thread.asBinder() != caller.asBinder())) {
16064                // Original caller already died
16065                return null;
16066            }
16067            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16068            if (rl == null) {
16069                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16070                        userId, receiver);
16071                if (rl.app != null) {
16072                    rl.app.receivers.add(rl);
16073                } else {
16074                    try {
16075                        receiver.asBinder().linkToDeath(rl, 0);
16076                    } catch (RemoteException e) {
16077                        return sticky;
16078                    }
16079                    rl.linkedToDeath = true;
16080                }
16081                mRegisteredReceivers.put(receiver.asBinder(), rl);
16082            } else if (rl.uid != callingUid) {
16083                throw new IllegalArgumentException(
16084                        "Receiver requested to register for uid " + callingUid
16085                        + " was previously registered for uid " + rl.uid);
16086            } else if (rl.pid != callingPid) {
16087                throw new IllegalArgumentException(
16088                        "Receiver requested to register for pid " + callingPid
16089                        + " was previously registered for pid " + rl.pid);
16090            } else if (rl.userId != userId) {
16091                throw new IllegalArgumentException(
16092                        "Receiver requested to register for user " + userId
16093                        + " was previously registered for user " + rl.userId);
16094            }
16095            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16096                    permission, callingUid, userId);
16097            rl.add(bf);
16098            if (!bf.debugCheck()) {
16099                Slog.w(TAG, "==> For Dynamic broadcast");
16100            }
16101            mReceiverResolver.addFilter(bf);
16102
16103            // Enqueue broadcasts for all existing stickies that match
16104            // this filter.
16105            if (allSticky != null) {
16106                ArrayList receivers = new ArrayList();
16107                receivers.add(bf);
16108
16109                final int stickyCount = allSticky.size();
16110                for (int i = 0; i < stickyCount; i++) {
16111                    Intent intent = allSticky.get(i);
16112                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16113                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16114                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16115                            null, 0, null, null, false, true, true, -1);
16116                    queue.enqueueParallelBroadcastLocked(r);
16117                    queue.scheduleBroadcastsLocked();
16118                }
16119            }
16120
16121            return sticky;
16122        }
16123    }
16124
16125    public void unregisterReceiver(IIntentReceiver receiver) {
16126        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16127
16128        final long origId = Binder.clearCallingIdentity();
16129        try {
16130            boolean doTrim = false;
16131
16132            synchronized(this) {
16133                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16134                if (rl != null) {
16135                    final BroadcastRecord r = rl.curBroadcast;
16136                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16137                        final boolean doNext = r.queue.finishReceiverLocked(
16138                                r, r.resultCode, r.resultData, r.resultExtras,
16139                                r.resultAbort, false);
16140                        if (doNext) {
16141                            doTrim = true;
16142                            r.queue.processNextBroadcast(false);
16143                        }
16144                    }
16145
16146                    if (rl.app != null) {
16147                        rl.app.receivers.remove(rl);
16148                    }
16149                    removeReceiverLocked(rl);
16150                    if (rl.linkedToDeath) {
16151                        rl.linkedToDeath = false;
16152                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16153                    }
16154                }
16155            }
16156
16157            // If we actually concluded any broadcasts, we might now be able
16158            // to trim the recipients' apps from our working set
16159            if (doTrim) {
16160                trimApplications();
16161                return;
16162            }
16163
16164        } finally {
16165            Binder.restoreCallingIdentity(origId);
16166        }
16167    }
16168
16169    void removeReceiverLocked(ReceiverList rl) {
16170        mRegisteredReceivers.remove(rl.receiver.asBinder());
16171        for (int i = rl.size() - 1; i >= 0; i--) {
16172            mReceiverResolver.removeFilter(rl.get(i));
16173        }
16174    }
16175
16176    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16177        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16178            ProcessRecord r = mLruProcesses.get(i);
16179            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16180                try {
16181                    r.thread.dispatchPackageBroadcast(cmd, packages);
16182                } catch (RemoteException ex) {
16183                }
16184            }
16185        }
16186    }
16187
16188    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16189            int callingUid, int[] users) {
16190        List<ResolveInfo> receivers = null;
16191        try {
16192            HashSet<ComponentName> singleUserReceivers = null;
16193            boolean scannedFirstReceivers = false;
16194            for (int user : users) {
16195                // Skip users that have Shell restrictions
16196                if (callingUid == Process.SHELL_UID
16197                        && getUserManagerLocked().hasUserRestriction(
16198                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16199                    continue;
16200                }
16201                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16202                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16203                if (user != UserHandle.USER_OWNER && newReceivers != null) {
16204                    // If this is not the primary user, we need to check for
16205                    // any receivers that should be filtered out.
16206                    for (int i=0; i<newReceivers.size(); i++) {
16207                        ResolveInfo ri = newReceivers.get(i);
16208                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16209                            newReceivers.remove(i);
16210                            i--;
16211                        }
16212                    }
16213                }
16214                if (newReceivers != null && newReceivers.size() == 0) {
16215                    newReceivers = null;
16216                }
16217                if (receivers == null) {
16218                    receivers = newReceivers;
16219                } else if (newReceivers != null) {
16220                    // We need to concatenate the additional receivers
16221                    // found with what we have do far.  This would be easy,
16222                    // but we also need to de-dup any receivers that are
16223                    // singleUser.
16224                    if (!scannedFirstReceivers) {
16225                        // Collect any single user receivers we had already retrieved.
16226                        scannedFirstReceivers = true;
16227                        for (int i=0; i<receivers.size(); i++) {
16228                            ResolveInfo ri = receivers.get(i);
16229                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16230                                ComponentName cn = new ComponentName(
16231                                        ri.activityInfo.packageName, ri.activityInfo.name);
16232                                if (singleUserReceivers == null) {
16233                                    singleUserReceivers = new HashSet<ComponentName>();
16234                                }
16235                                singleUserReceivers.add(cn);
16236                            }
16237                        }
16238                    }
16239                    // Add the new results to the existing results, tracking
16240                    // and de-dupping single user receivers.
16241                    for (int i=0; i<newReceivers.size(); i++) {
16242                        ResolveInfo ri = newReceivers.get(i);
16243                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16244                            ComponentName cn = new ComponentName(
16245                                    ri.activityInfo.packageName, ri.activityInfo.name);
16246                            if (singleUserReceivers == null) {
16247                                singleUserReceivers = new HashSet<ComponentName>();
16248                            }
16249                            if (!singleUserReceivers.contains(cn)) {
16250                                singleUserReceivers.add(cn);
16251                                receivers.add(ri);
16252                            }
16253                        } else {
16254                            receivers.add(ri);
16255                        }
16256                    }
16257                }
16258            }
16259        } catch (RemoteException ex) {
16260            // pm is in same process, this will never happen.
16261        }
16262        return receivers;
16263    }
16264
16265    private final int broadcastIntentLocked(ProcessRecord callerApp,
16266            String callerPackage, Intent intent, String resolvedType,
16267            IIntentReceiver resultTo, int resultCode, String resultData,
16268            Bundle resultExtras, String requiredPermission, int appOp, Bundle options,
16269            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16270        intent = new Intent(intent);
16271
16272        // By default broadcasts do not go to stopped apps.
16273        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16274
16275        // If we have not finished booting, don't allow this to launch new processes.
16276        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16277            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16278        }
16279
16280        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16281                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16282                + " ordered=" + ordered + " userid=" + userId);
16283        if ((resultTo != null) && !ordered) {
16284            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16285        }
16286
16287        userId = handleIncomingUser(callingPid, callingUid, userId,
16288                true, ALLOW_NON_FULL, "broadcast", callerPackage);
16289
16290        // Make sure that the user who is receiving this broadcast is running.
16291        // If not, we will just skip it. Make an exception for shutdown broadcasts
16292        // and upgrade steps.
16293
16294        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16295            if ((callingUid != Process.SYSTEM_UID
16296                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16297                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16298                Slog.w(TAG, "Skipping broadcast of " + intent
16299                        + ": user " + userId + " is stopped");
16300                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16301            }
16302        }
16303
16304        BroadcastOptions brOptions = null;
16305        if (options != null) {
16306            brOptions = new BroadcastOptions(options);
16307            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16308                // See if the caller is allowed to do this.  Note we are checking against
16309                // the actual real caller (not whoever provided the operation as say a
16310                // PendingIntent), because that who is actually supplied the arguments.
16311                if (checkComponentPermission(
16312                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16313                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16314                        != PackageManager.PERMISSION_GRANTED) {
16315                    String msg = "Permission Denial: " + intent.getAction()
16316                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16317                            + ", uid=" + callingUid + ")"
16318                            + " requires "
16319                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16320                    Slog.w(TAG, msg);
16321                    throw new SecurityException(msg);
16322                }
16323            }
16324        }
16325
16326        /*
16327         * Prevent non-system code (defined here to be non-persistent
16328         * processes) from sending protected broadcasts.
16329         */
16330        int callingAppId = UserHandle.getAppId(callingUid);
16331        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16332            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16333            || callingAppId == Process.NFC_UID || callingUid == 0) {
16334            // Always okay.
16335        } else if (callerApp == null || !callerApp.persistent) {
16336            try {
16337                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16338                        intent.getAction())) {
16339                    String msg = "Permission Denial: not allowed to send broadcast "
16340                            + intent.getAction() + " from pid="
16341                            + callingPid + ", uid=" + callingUid;
16342                    Slog.w(TAG, msg);
16343                    throw new SecurityException(msg);
16344                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16345                    // Special case for compatibility: we don't want apps to send this,
16346                    // but historically it has not been protected and apps may be using it
16347                    // to poke their own app widget.  So, instead of making it protected,
16348                    // just limit it to the caller.
16349                    if (callerApp == null) {
16350                        String msg = "Permission Denial: not allowed to send broadcast "
16351                                + intent.getAction() + " from unknown caller.";
16352                        Slog.w(TAG, msg);
16353                        throw new SecurityException(msg);
16354                    } else if (intent.getComponent() != null) {
16355                        // They are good enough to send to an explicit component...  verify
16356                        // it is being sent to the calling app.
16357                        if (!intent.getComponent().getPackageName().equals(
16358                                callerApp.info.packageName)) {
16359                            String msg = "Permission Denial: not allowed to send broadcast "
16360                                    + intent.getAction() + " to "
16361                                    + intent.getComponent().getPackageName() + " from "
16362                                    + callerApp.info.packageName;
16363                            Slog.w(TAG, msg);
16364                            throw new SecurityException(msg);
16365                        }
16366                    } else {
16367                        // Limit broadcast to their own package.
16368                        intent.setPackage(callerApp.info.packageName);
16369                    }
16370                }
16371            } catch (RemoteException e) {
16372                Slog.w(TAG, "Remote exception", e);
16373                return ActivityManager.BROADCAST_SUCCESS;
16374            }
16375        }
16376
16377        final String action = intent.getAction();
16378        if (action != null) {
16379            switch (action) {
16380                case Intent.ACTION_UID_REMOVED:
16381                case Intent.ACTION_PACKAGE_REMOVED:
16382                case Intent.ACTION_PACKAGE_CHANGED:
16383                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16384                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16385                    // Handle special intents: if this broadcast is from the package
16386                    // manager about a package being removed, we need to remove all of
16387                    // its activities from the history stack.
16388                    if (checkComponentPermission(
16389                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16390                            callingPid, callingUid, -1, true)
16391                            != PackageManager.PERMISSION_GRANTED) {
16392                        String msg = "Permission Denial: " + intent.getAction()
16393                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16394                                + ", uid=" + callingUid + ")"
16395                                + " requires "
16396                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16397                        Slog.w(TAG, msg);
16398                        throw new SecurityException(msg);
16399                    }
16400                    switch (action) {
16401                        case Intent.ACTION_UID_REMOVED:
16402                            final Bundle intentExtras = intent.getExtras();
16403                            final int uid = intentExtras != null
16404                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16405                            if (uid >= 0) {
16406                                mBatteryStatsService.removeUid(uid);
16407                                mAppOpsService.uidRemoved(uid);
16408                            }
16409                            break;
16410                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16411                            // If resources are unavailable just force stop all those packages
16412                            // and flush the attribute cache as well.
16413                            String list[] =
16414                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16415                            if (list != null && list.length > 0) {
16416                                for (int i = 0; i < list.length; i++) {
16417                                    forceStopPackageLocked(list[i], -1, false, true, true,
16418                                            false, false, userId, "storage unmount");
16419                                }
16420                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16421                                sendPackageBroadcastLocked(
16422                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16423                                        userId);
16424                            }
16425                            break;
16426                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16427                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16428                            break;
16429                        case Intent.ACTION_PACKAGE_REMOVED:
16430                        case Intent.ACTION_PACKAGE_CHANGED:
16431                            Uri data = intent.getData();
16432                            String ssp;
16433                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16434                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16435                                boolean fullUninstall = removed &&
16436                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16437                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16438                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16439                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16440                                            false, true, true, false, fullUninstall, userId,
16441                                            removed ? "pkg removed" : "pkg changed");
16442                                }
16443                                if (removed) {
16444                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16445                                            new String[] {ssp}, userId);
16446                                    if (fullUninstall) {
16447                                        mAppOpsService.packageRemoved(
16448                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16449
16450                                        // Remove all permissions granted from/to this package
16451                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16452
16453                                        removeTasksByPackageNameLocked(ssp, userId);
16454                                        mBatteryStatsService.notePackageUninstalled(ssp);
16455                                    }
16456                                } else {
16457                                    cleanupDisabledPackageComponentsLocked(ssp, userId,
16458                                            intent.getStringArrayExtra(
16459                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16460                                }
16461                            }
16462                            break;
16463                    }
16464                    break;
16465                case Intent.ACTION_PACKAGE_ADDED:
16466                    // Special case for adding a package: by default turn on compatibility mode.
16467                    Uri data = intent.getData();
16468                    String ssp;
16469                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16470                        final boolean replacing =
16471                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16472                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16473
16474                        try {
16475                            ApplicationInfo ai = AppGlobals.getPackageManager().
16476                                    getApplicationInfo(ssp, 0, 0);
16477                            mBatteryStatsService.notePackageInstalled(ssp,
16478                                    ai != null ? ai.versionCode : 0);
16479                        } catch (RemoteException e) {
16480                        }
16481                    }
16482                    break;
16483                case Intent.ACTION_TIMEZONE_CHANGED:
16484                    // If this is the time zone changed action, queue up a message that will reset
16485                    // the timezone of all currently running processes. This message will get
16486                    // queued up before the broadcast happens.
16487                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16488                    break;
16489                case Intent.ACTION_TIME_CHANGED:
16490                    // If the user set the time, let all running processes know.
16491                    final int is24Hour =
16492                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16493                                    : 0;
16494                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16495                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16496                    synchronized (stats) {
16497                        stats.noteCurrentTimeChangedLocked();
16498                    }
16499                    break;
16500                case Intent.ACTION_CLEAR_DNS_CACHE:
16501                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16502                    break;
16503                case Proxy.PROXY_CHANGE_ACTION:
16504                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16505                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16506                    break;
16507            }
16508        }
16509
16510        // Add to the sticky list if requested.
16511        if (sticky) {
16512            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16513                    callingPid, callingUid)
16514                    != PackageManager.PERMISSION_GRANTED) {
16515                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16516                        + callingPid + ", uid=" + callingUid
16517                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16518                Slog.w(TAG, msg);
16519                throw new SecurityException(msg);
16520            }
16521            if (requiredPermission != null) {
16522                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16523                        + " and enforce permission " + requiredPermission);
16524                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16525            }
16526            if (intent.getComponent() != null) {
16527                throw new SecurityException(
16528                        "Sticky broadcasts can't target a specific component");
16529            }
16530            // We use userId directly here, since the "all" target is maintained
16531            // as a separate set of sticky broadcasts.
16532            if (userId != UserHandle.USER_ALL) {
16533                // But first, if this is not a broadcast to all users, then
16534                // make sure it doesn't conflict with an existing broadcast to
16535                // all users.
16536                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16537                        UserHandle.USER_ALL);
16538                if (stickies != null) {
16539                    ArrayList<Intent> list = stickies.get(intent.getAction());
16540                    if (list != null) {
16541                        int N = list.size();
16542                        int i;
16543                        for (i=0; i<N; i++) {
16544                            if (intent.filterEquals(list.get(i))) {
16545                                throw new IllegalArgumentException(
16546                                        "Sticky broadcast " + intent + " for user "
16547                                        + userId + " conflicts with existing global broadcast");
16548                            }
16549                        }
16550                    }
16551                }
16552            }
16553            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16554            if (stickies == null) {
16555                stickies = new ArrayMap<>();
16556                mStickyBroadcasts.put(userId, stickies);
16557            }
16558            ArrayList<Intent> list = stickies.get(intent.getAction());
16559            if (list == null) {
16560                list = new ArrayList<>();
16561                stickies.put(intent.getAction(), list);
16562            }
16563            final int stickiesCount = list.size();
16564            int i;
16565            for (i = 0; i < stickiesCount; i++) {
16566                if (intent.filterEquals(list.get(i))) {
16567                    // This sticky already exists, replace it.
16568                    list.set(i, new Intent(intent));
16569                    break;
16570                }
16571            }
16572            if (i >= stickiesCount) {
16573                list.add(new Intent(intent));
16574            }
16575        }
16576
16577        int[] users;
16578        if (userId == UserHandle.USER_ALL) {
16579            // Caller wants broadcast to go to all started users.
16580            users = mStartedUserArray;
16581        } else {
16582            // Caller wants broadcast to go to one specific user.
16583            users = new int[] {userId};
16584        }
16585
16586        // Figure out who all will receive this broadcast.
16587        List receivers = null;
16588        List<BroadcastFilter> registeredReceivers = null;
16589        // Need to resolve the intent to interested receivers...
16590        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16591                 == 0) {
16592            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16593        }
16594        if (intent.getComponent() == null) {
16595            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16596                // Query one target user at a time, excluding shell-restricted users
16597                UserManagerService ums = getUserManagerLocked();
16598                for (int i = 0; i < users.length; i++) {
16599                    if (ums.hasUserRestriction(
16600                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16601                        continue;
16602                    }
16603                    List<BroadcastFilter> registeredReceiversForUser =
16604                            mReceiverResolver.queryIntent(intent,
16605                                    resolvedType, false, users[i]);
16606                    if (registeredReceivers == null) {
16607                        registeredReceivers = registeredReceiversForUser;
16608                    } else if (registeredReceiversForUser != null) {
16609                        registeredReceivers.addAll(registeredReceiversForUser);
16610                    }
16611                }
16612            } else {
16613                registeredReceivers = mReceiverResolver.queryIntent(intent,
16614                        resolvedType, false, userId);
16615            }
16616        }
16617
16618        final boolean replacePending =
16619                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16620
16621        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16622                + " replacePending=" + replacePending);
16623
16624        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16625        if (!ordered && NR > 0) {
16626            // If we are not serializing this broadcast, then send the
16627            // registered receivers separately so they don't wait for the
16628            // components to be launched.
16629            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16630            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16631                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16632                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16633                    resultExtras, ordered, sticky, false, userId);
16634            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16635            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16636            if (!replaced) {
16637                queue.enqueueParallelBroadcastLocked(r);
16638                queue.scheduleBroadcastsLocked();
16639            }
16640            registeredReceivers = null;
16641            NR = 0;
16642        }
16643
16644        // Merge into one list.
16645        int ir = 0;
16646        if (receivers != null) {
16647            // A special case for PACKAGE_ADDED: do not allow the package
16648            // being added to see this broadcast.  This prevents them from
16649            // using this as a back door to get run as soon as they are
16650            // installed.  Maybe in the future we want to have a special install
16651            // broadcast or such for apps, but we'd like to deliberately make
16652            // this decision.
16653            String skipPackages[] = null;
16654            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16655                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16656                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16657                Uri data = intent.getData();
16658                if (data != null) {
16659                    String pkgName = data.getSchemeSpecificPart();
16660                    if (pkgName != null) {
16661                        skipPackages = new String[] { pkgName };
16662                    }
16663                }
16664            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16665                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16666            }
16667            if (skipPackages != null && (skipPackages.length > 0)) {
16668                for (String skipPackage : skipPackages) {
16669                    if (skipPackage != null) {
16670                        int NT = receivers.size();
16671                        for (int it=0; it<NT; it++) {
16672                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16673                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16674                                receivers.remove(it);
16675                                it--;
16676                                NT--;
16677                            }
16678                        }
16679                    }
16680                }
16681            }
16682
16683            int NT = receivers != null ? receivers.size() : 0;
16684            int it = 0;
16685            ResolveInfo curt = null;
16686            BroadcastFilter curr = null;
16687            while (it < NT && ir < NR) {
16688                if (curt == null) {
16689                    curt = (ResolveInfo)receivers.get(it);
16690                }
16691                if (curr == null) {
16692                    curr = registeredReceivers.get(ir);
16693                }
16694                if (curr.getPriority() >= curt.priority) {
16695                    // Insert this broadcast record into the final list.
16696                    receivers.add(it, curr);
16697                    ir++;
16698                    curr = null;
16699                    it++;
16700                    NT++;
16701                } else {
16702                    // Skip to the next ResolveInfo in the final list.
16703                    it++;
16704                    curt = null;
16705                }
16706            }
16707        }
16708        while (ir < NR) {
16709            if (receivers == null) {
16710                receivers = new ArrayList();
16711            }
16712            receivers.add(registeredReceivers.get(ir));
16713            ir++;
16714        }
16715
16716        if ((receivers != null && receivers.size() > 0)
16717                || resultTo != null) {
16718            BroadcastQueue queue = broadcastQueueForIntent(intent);
16719            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16720                    callerPackage, callingPid, callingUid, resolvedType,
16721                    requiredPermission, appOp, brOptions, receivers, resultTo, resultCode,
16722                    resultData, resultExtras, ordered, sticky, false, userId);
16723
16724            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16725                    + ": prev had " + queue.mOrderedBroadcasts.size());
16726            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16727                    "Enqueueing broadcast " + r.intent.getAction());
16728
16729            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16730            if (!replaced) {
16731                queue.enqueueOrderedBroadcastLocked(r);
16732                queue.scheduleBroadcastsLocked();
16733            }
16734        }
16735
16736        return ActivityManager.BROADCAST_SUCCESS;
16737    }
16738
16739    final Intent verifyBroadcastLocked(Intent intent) {
16740        // Refuse possible leaked file descriptors
16741        if (intent != null && intent.hasFileDescriptors() == true) {
16742            throw new IllegalArgumentException("File descriptors passed in Intent");
16743        }
16744
16745        int flags = intent.getFlags();
16746
16747        if (!mProcessesReady) {
16748            // if the caller really truly claims to know what they're doing, go
16749            // ahead and allow the broadcast without launching any receivers
16750            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16751                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16752            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16753                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16754                        + " before boot completion");
16755                throw new IllegalStateException("Cannot broadcast before boot completed");
16756            }
16757        }
16758
16759        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16760            throw new IllegalArgumentException(
16761                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16762        }
16763
16764        return intent;
16765    }
16766
16767    public final int broadcastIntent(IApplicationThread caller,
16768            Intent intent, String resolvedType, IIntentReceiver resultTo,
16769            int resultCode, String resultData, Bundle resultExtras,
16770            String requiredPermission, int appOp, Bundle options,
16771            boolean serialized, boolean sticky, int userId) {
16772        enforceNotIsolatedCaller("broadcastIntent");
16773        synchronized(this) {
16774            intent = verifyBroadcastLocked(intent);
16775
16776            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16777            final int callingPid = Binder.getCallingPid();
16778            final int callingUid = Binder.getCallingUid();
16779            final long origId = Binder.clearCallingIdentity();
16780            int res = broadcastIntentLocked(callerApp,
16781                    callerApp != null ? callerApp.info.packageName : null,
16782                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
16783                    requiredPermission, appOp, null, serialized, sticky,
16784                    callingPid, callingUid, userId);
16785            Binder.restoreCallingIdentity(origId);
16786            return res;
16787        }
16788    }
16789
16790    int broadcastIntentInPackage(String packageName, int uid,
16791            Intent intent, String resolvedType, IIntentReceiver resultTo,
16792            int resultCode, String resultData, Bundle resultExtras,
16793            String requiredPermission, Bundle options, boolean serialized, boolean sticky,
16794            int userId) {
16795        synchronized(this) {
16796            intent = verifyBroadcastLocked(intent);
16797
16798            final long origId = Binder.clearCallingIdentity();
16799            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16800                    resultTo, resultCode, resultData, resultExtras, requiredPermission,
16801                    AppOpsManager.OP_NONE, options, serialized, sticky, -1, uid, userId);
16802            Binder.restoreCallingIdentity(origId);
16803            return res;
16804        }
16805    }
16806
16807    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16808        // Refuse possible leaked file descriptors
16809        if (intent != null && intent.hasFileDescriptors() == true) {
16810            throw new IllegalArgumentException("File descriptors passed in Intent");
16811        }
16812
16813        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16814                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16815
16816        synchronized(this) {
16817            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16818                    != PackageManager.PERMISSION_GRANTED) {
16819                String msg = "Permission Denial: unbroadcastIntent() from pid="
16820                        + Binder.getCallingPid()
16821                        + ", uid=" + Binder.getCallingUid()
16822                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16823                Slog.w(TAG, msg);
16824                throw new SecurityException(msg);
16825            }
16826            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16827            if (stickies != null) {
16828                ArrayList<Intent> list = stickies.get(intent.getAction());
16829                if (list != null) {
16830                    int N = list.size();
16831                    int i;
16832                    for (i=0; i<N; i++) {
16833                        if (intent.filterEquals(list.get(i))) {
16834                            list.remove(i);
16835                            break;
16836                        }
16837                    }
16838                    if (list.size() <= 0) {
16839                        stickies.remove(intent.getAction());
16840                    }
16841                }
16842                if (stickies.size() <= 0) {
16843                    mStickyBroadcasts.remove(userId);
16844                }
16845            }
16846        }
16847    }
16848
16849    void backgroundServicesFinishedLocked(int userId) {
16850        for (BroadcastQueue queue : mBroadcastQueues) {
16851            queue.backgroundServicesFinishedLocked(userId);
16852        }
16853    }
16854
16855    public void finishReceiver(IBinder who, int resultCode, String resultData,
16856            Bundle resultExtras, boolean resultAbort, int flags) {
16857        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
16858
16859        // Refuse possible leaked file descriptors
16860        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16861            throw new IllegalArgumentException("File descriptors passed in Bundle");
16862        }
16863
16864        final long origId = Binder.clearCallingIdentity();
16865        try {
16866            boolean doNext = false;
16867            BroadcastRecord r;
16868
16869            synchronized(this) {
16870                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16871                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16872                r = queue.getMatchingOrderedReceiver(who);
16873                if (r != null) {
16874                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16875                        resultData, resultExtras, resultAbort, true);
16876                }
16877            }
16878
16879            if (doNext) {
16880                r.queue.processNextBroadcast(false);
16881            }
16882            trimApplications();
16883        } finally {
16884            Binder.restoreCallingIdentity(origId);
16885        }
16886    }
16887
16888    // =========================================================
16889    // INSTRUMENTATION
16890    // =========================================================
16891
16892    public boolean startInstrumentation(ComponentName className,
16893            String profileFile, int flags, Bundle arguments,
16894            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16895            int userId, String abiOverride) {
16896        enforceNotIsolatedCaller("startInstrumentation");
16897        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16898                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16899        // Refuse possible leaked file descriptors
16900        if (arguments != null && arguments.hasFileDescriptors()) {
16901            throw new IllegalArgumentException("File descriptors passed in Bundle");
16902        }
16903
16904        synchronized(this) {
16905            InstrumentationInfo ii = null;
16906            ApplicationInfo ai = null;
16907            try {
16908                ii = mContext.getPackageManager().getInstrumentationInfo(
16909                    className, STOCK_PM_FLAGS);
16910                ai = AppGlobals.getPackageManager().getApplicationInfo(
16911                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16912            } catch (PackageManager.NameNotFoundException e) {
16913            } catch (RemoteException e) {
16914            }
16915            if (ii == null) {
16916                reportStartInstrumentationFailure(watcher, className,
16917                        "Unable to find instrumentation info for: " + className);
16918                return false;
16919            }
16920            if (ai == null) {
16921                reportStartInstrumentationFailure(watcher, className,
16922                        "Unable to find instrumentation target package: " + ii.targetPackage);
16923                return false;
16924            }
16925
16926            int match = mContext.getPackageManager().checkSignatures(
16927                    ii.targetPackage, ii.packageName);
16928            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16929                String msg = "Permission Denial: starting instrumentation "
16930                        + className + " from pid="
16931                        + Binder.getCallingPid()
16932                        + ", uid=" + Binder.getCallingPid()
16933                        + " not allowed because package " + ii.packageName
16934                        + " does not have a signature matching the target "
16935                        + ii.targetPackage;
16936                reportStartInstrumentationFailure(watcher, className, msg);
16937                throw new SecurityException(msg);
16938            }
16939
16940            final long origId = Binder.clearCallingIdentity();
16941            // Instrumentation can kill and relaunch even persistent processes
16942            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16943                    "start instr");
16944            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16945            app.instrumentationClass = className;
16946            app.instrumentationInfo = ai;
16947            app.instrumentationProfileFile = profileFile;
16948            app.instrumentationArguments = arguments;
16949            app.instrumentationWatcher = watcher;
16950            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16951            app.instrumentationResultClass = className;
16952            Binder.restoreCallingIdentity(origId);
16953        }
16954
16955        return true;
16956    }
16957
16958    /**
16959     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16960     * error to the logs, but if somebody is watching, send the report there too.  This enables
16961     * the "am" command to report errors with more information.
16962     *
16963     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16964     * @param cn The component name of the instrumentation.
16965     * @param report The error report.
16966     */
16967    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16968            ComponentName cn, String report) {
16969        Slog.w(TAG, report);
16970        try {
16971            if (watcher != null) {
16972                Bundle results = new Bundle();
16973                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16974                results.putString("Error", report);
16975                watcher.instrumentationStatus(cn, -1, results);
16976            }
16977        } catch (RemoteException e) {
16978            Slog.w(TAG, e);
16979        }
16980    }
16981
16982    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16983        if (app.instrumentationWatcher != null) {
16984            try {
16985                // NOTE:  IInstrumentationWatcher *must* be oneway here
16986                app.instrumentationWatcher.instrumentationFinished(
16987                    app.instrumentationClass,
16988                    resultCode,
16989                    results);
16990            } catch (RemoteException e) {
16991            }
16992        }
16993        if (app.instrumentationUiAutomationConnection != null) {
16994            try {
16995                app.instrumentationUiAutomationConnection.shutdown();
16996            } catch (RemoteException re) {
16997                /* ignore */
16998            }
16999            // Only a UiAutomation can set this flag and now that
17000            // it is finished we make sure it is reset to its default.
17001            mUserIsMonkey = false;
17002        }
17003        app.instrumentationWatcher = null;
17004        app.instrumentationUiAutomationConnection = null;
17005        app.instrumentationClass = null;
17006        app.instrumentationInfo = null;
17007        app.instrumentationProfileFile = null;
17008        app.instrumentationArguments = null;
17009
17010        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17011                "finished inst");
17012    }
17013
17014    public void finishInstrumentation(IApplicationThread target,
17015            int resultCode, Bundle results) {
17016        int userId = UserHandle.getCallingUserId();
17017        // Refuse possible leaked file descriptors
17018        if (results != null && results.hasFileDescriptors()) {
17019            throw new IllegalArgumentException("File descriptors passed in Intent");
17020        }
17021
17022        synchronized(this) {
17023            ProcessRecord app = getRecordForAppLocked(target);
17024            if (app == null) {
17025                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17026                return;
17027            }
17028            final long origId = Binder.clearCallingIdentity();
17029            finishInstrumentationLocked(app, resultCode, results);
17030            Binder.restoreCallingIdentity(origId);
17031        }
17032    }
17033
17034    // =========================================================
17035    // CONFIGURATION
17036    // =========================================================
17037
17038    public ConfigurationInfo getDeviceConfigurationInfo() {
17039        ConfigurationInfo config = new ConfigurationInfo();
17040        synchronized (this) {
17041            config.reqTouchScreen = mConfiguration.touchscreen;
17042            config.reqKeyboardType = mConfiguration.keyboard;
17043            config.reqNavigation = mConfiguration.navigation;
17044            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17045                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17046                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17047            }
17048            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17049                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17050                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17051            }
17052            config.reqGlEsVersion = GL_ES_VERSION;
17053        }
17054        return config;
17055    }
17056
17057    ActivityStack getFocusedStack() {
17058        return mStackSupervisor.getFocusedStack();
17059    }
17060
17061    @Override
17062    public int getFocusedStackId() throws RemoteException {
17063        ActivityStack focusedStack = getFocusedStack();
17064        if (focusedStack != null) {
17065            return focusedStack.getStackId();
17066        }
17067        return -1;
17068    }
17069
17070    public Configuration getConfiguration() {
17071        Configuration ci;
17072        synchronized(this) {
17073            ci = new Configuration(mConfiguration);
17074            ci.userSetLocale = false;
17075        }
17076        return ci;
17077    }
17078
17079    public void updatePersistentConfiguration(Configuration values) {
17080        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17081                "updateConfiguration()");
17082        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
17083                "updateConfiguration()");
17084        if (values == null) {
17085            throw new NullPointerException("Configuration must not be null");
17086        }
17087
17088        synchronized(this) {
17089            final long origId = Binder.clearCallingIdentity();
17090            updateConfigurationLocked(values, null, true, false);
17091            Binder.restoreCallingIdentity(origId);
17092        }
17093    }
17094
17095    public void updateConfiguration(Configuration values) {
17096        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17097                "updateConfiguration()");
17098
17099        synchronized(this) {
17100            if (values == null && mWindowManager != null) {
17101                // sentinel: fetch the current configuration from the window manager
17102                values = mWindowManager.computeNewConfiguration();
17103            }
17104
17105            if (mWindowManager != null) {
17106                mProcessList.applyDisplaySize(mWindowManager);
17107            }
17108
17109            final long origId = Binder.clearCallingIdentity();
17110            if (values != null) {
17111                Settings.System.clearConfiguration(values);
17112            }
17113            updateConfigurationLocked(values, null, false, false);
17114            Binder.restoreCallingIdentity(origId);
17115        }
17116    }
17117
17118    /**
17119     * Do either or both things: (1) change the current configuration, and (2)
17120     * make sure the given activity is running with the (now) current
17121     * configuration.  Returns true if the activity has been left running, or
17122     * false if <var>starting</var> is being destroyed to match the new
17123     * configuration.
17124     * @param persistent TODO
17125     */
17126    boolean updateConfigurationLocked(Configuration values,
17127            ActivityRecord starting, boolean persistent, boolean initLocale) {
17128        int changes = 0;
17129
17130        if (values != null) {
17131            Configuration newConfig = new Configuration(mConfiguration);
17132            changes = newConfig.updateFrom(values);
17133            if (changes != 0) {
17134                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17135                        "Updating configuration to: " + values);
17136
17137                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17138
17139                if (!initLocale && values.locale != null && values.userSetLocale) {
17140                    final String languageTag = values.locale.toLanguageTag();
17141                    SystemProperties.set("persist.sys.locale", languageTag);
17142                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17143                            values.locale));
17144                }
17145
17146                mConfigurationSeq++;
17147                if (mConfigurationSeq <= 0) {
17148                    mConfigurationSeq = 1;
17149                }
17150                newConfig.seq = mConfigurationSeq;
17151                mConfiguration = newConfig;
17152                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17153                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17154                //mUsageStatsService.noteStartConfig(newConfig);
17155
17156                final Configuration configCopy = new Configuration(mConfiguration);
17157
17158                // TODO: If our config changes, should we auto dismiss any currently
17159                // showing dialogs?
17160                mShowDialogs = shouldShowDialogs(newConfig);
17161
17162                AttributeCache ac = AttributeCache.instance();
17163                if (ac != null) {
17164                    ac.updateConfiguration(configCopy);
17165                }
17166
17167                // Make sure all resources in our process are updated
17168                // right now, so that anyone who is going to retrieve
17169                // resource values after we return will be sure to get
17170                // the new ones.  This is especially important during
17171                // boot, where the first config change needs to guarantee
17172                // all resources have that config before following boot
17173                // code is executed.
17174                mSystemThread.applyConfigurationToResources(configCopy);
17175
17176                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17177                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17178                    msg.obj = new Configuration(configCopy);
17179                    mHandler.sendMessage(msg);
17180                }
17181
17182                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17183                    ProcessRecord app = mLruProcesses.get(i);
17184                    try {
17185                        if (app.thread != null) {
17186                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17187                                    + app.processName + " new config " + mConfiguration);
17188                            app.thread.scheduleConfigurationChanged(configCopy);
17189                        }
17190                    } catch (Exception e) {
17191                    }
17192                }
17193                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17194                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17195                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17196                        | Intent.FLAG_RECEIVER_FOREGROUND);
17197                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17198                        null, AppOpsManager.OP_NONE, null, false, false,
17199                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17200                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17201                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17202                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17203                    if (!mProcessesReady) {
17204                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17205                    }
17206                    broadcastIntentLocked(null, null, intent,
17207                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17208                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17209                }
17210            }
17211        }
17212
17213        boolean kept = true;
17214        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17215        // mainStack is null during startup.
17216        if (mainStack != null) {
17217            if (changes != 0 && starting == null) {
17218                // If the configuration changed, and the caller is not already
17219                // in the process of starting an activity, then find the top
17220                // activity to check if its configuration needs to change.
17221                starting = mainStack.topRunningActivityLocked(null);
17222            }
17223
17224            if (starting != null) {
17225                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17226                // And we need to make sure at this point that all other activities
17227                // are made visible with the correct configuration.
17228                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17229            }
17230        }
17231
17232        if (values != null && mWindowManager != null) {
17233            mWindowManager.setNewConfiguration(mConfiguration);
17234        }
17235
17236        return kept;
17237    }
17238
17239    /**
17240     * Decide based on the configuration whether we should shouw the ANR,
17241     * crash, etc dialogs.  The idea is that if there is no affordnace to
17242     * press the on-screen buttons, we shouldn't show the dialog.
17243     *
17244     * A thought: SystemUI might also want to get told about this, the Power
17245     * dialog / global actions also might want different behaviors.
17246     */
17247    private static final boolean shouldShowDialogs(Configuration config) {
17248        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17249                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17250                && config.navigation == Configuration.NAVIGATION_NONAV);
17251    }
17252
17253    @Override
17254    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17255        synchronized (this) {
17256            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17257            if (srec != null) {
17258                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17259            }
17260        }
17261        return false;
17262    }
17263
17264    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17265            Intent resultData) {
17266
17267        synchronized (this) {
17268            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17269            if (r != null) {
17270                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17271            }
17272            return false;
17273        }
17274    }
17275
17276    public int getLaunchedFromUid(IBinder activityToken) {
17277        ActivityRecord srec;
17278        synchronized (this) {
17279            srec = ActivityRecord.forTokenLocked(activityToken);
17280        }
17281        if (srec == null) {
17282            return -1;
17283        }
17284        return srec.launchedFromUid;
17285    }
17286
17287    public String getLaunchedFromPackage(IBinder activityToken) {
17288        ActivityRecord srec;
17289        synchronized (this) {
17290            srec = ActivityRecord.forTokenLocked(activityToken);
17291        }
17292        if (srec == null) {
17293            return null;
17294        }
17295        return srec.launchedFromPackage;
17296    }
17297
17298    // =========================================================
17299    // LIFETIME MANAGEMENT
17300    // =========================================================
17301
17302    // Returns which broadcast queue the app is the current [or imminent] receiver
17303    // on, or 'null' if the app is not an active broadcast recipient.
17304    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17305        BroadcastRecord r = app.curReceiver;
17306        if (r != null) {
17307            return r.queue;
17308        }
17309
17310        // It's not the current receiver, but it might be starting up to become one
17311        synchronized (this) {
17312            for (BroadcastQueue queue : mBroadcastQueues) {
17313                r = queue.mPendingBroadcast;
17314                if (r != null && r.curApp == app) {
17315                    // found it; report which queue it's in
17316                    return queue;
17317                }
17318            }
17319        }
17320
17321        return null;
17322    }
17323
17324    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17325            ComponentName targetComponent, String targetProcess) {
17326        if (!mTrackingAssociations) {
17327            return null;
17328        }
17329        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17330                = mAssociations.get(targetUid);
17331        if (components == null) {
17332            components = new ArrayMap<>();
17333            mAssociations.put(targetUid, components);
17334        }
17335        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17336        if (sourceUids == null) {
17337            sourceUids = new SparseArray<>();
17338            components.put(targetComponent, sourceUids);
17339        }
17340        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17341        if (sourceProcesses == null) {
17342            sourceProcesses = new ArrayMap<>();
17343            sourceUids.put(sourceUid, sourceProcesses);
17344        }
17345        Association ass = sourceProcesses.get(sourceProcess);
17346        if (ass == null) {
17347            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17348                    targetProcess);
17349            sourceProcesses.put(sourceProcess, ass);
17350        }
17351        ass.mCount++;
17352        ass.mNesting++;
17353        if (ass.mNesting == 1) {
17354            ass.mStartTime = SystemClock.uptimeMillis();
17355        }
17356        return ass;
17357    }
17358
17359    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17360            ComponentName targetComponent) {
17361        if (!mTrackingAssociations) {
17362            return;
17363        }
17364        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17365                = mAssociations.get(targetUid);
17366        if (components == null) {
17367            return;
17368        }
17369        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17370        if (sourceUids == null) {
17371            return;
17372        }
17373        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17374        if (sourceProcesses == null) {
17375            return;
17376        }
17377        Association ass = sourceProcesses.get(sourceProcess);
17378        if (ass == null || ass.mNesting <= 0) {
17379            return;
17380        }
17381        ass.mNesting--;
17382        if (ass.mNesting == 0) {
17383            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17384        }
17385    }
17386
17387    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17388            boolean doingAll, long now) {
17389        if (mAdjSeq == app.adjSeq) {
17390            // This adjustment has already been computed.
17391            return app.curRawAdj;
17392        }
17393
17394        if (app.thread == null) {
17395            app.adjSeq = mAdjSeq;
17396            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17397            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17398            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17399        }
17400
17401        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17402        app.adjSource = null;
17403        app.adjTarget = null;
17404        app.empty = false;
17405        app.cached = false;
17406
17407        final int activitiesSize = app.activities.size();
17408
17409        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17410            // The max adjustment doesn't allow this app to be anything
17411            // below foreground, so it is not worth doing work for it.
17412            app.adjType = "fixed";
17413            app.adjSeq = mAdjSeq;
17414            app.curRawAdj = app.maxAdj;
17415            app.foregroundActivities = false;
17416            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17417            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17418            // System processes can do UI, and when they do we want to have
17419            // them trim their memory after the user leaves the UI.  To
17420            // facilitate this, here we need to determine whether or not it
17421            // is currently showing UI.
17422            app.systemNoUi = true;
17423            if (app == TOP_APP) {
17424                app.systemNoUi = false;
17425            } else if (activitiesSize > 0) {
17426                for (int j = 0; j < activitiesSize; j++) {
17427                    final ActivityRecord r = app.activities.get(j);
17428                    if (r.visible) {
17429                        app.systemNoUi = false;
17430                    }
17431                }
17432            }
17433            if (!app.systemNoUi) {
17434                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17435            }
17436            return (app.curAdj=app.maxAdj);
17437        }
17438
17439        app.systemNoUi = false;
17440
17441        final int PROCESS_STATE_TOP = mTopProcessState;
17442
17443        // Determine the importance of the process, starting with most
17444        // important to least, and assign an appropriate OOM adjustment.
17445        int adj;
17446        int schedGroup;
17447        int procState;
17448        boolean foregroundActivities = false;
17449        BroadcastQueue queue;
17450        if (app == TOP_APP) {
17451            // The last app on the list is the foreground app.
17452            adj = ProcessList.FOREGROUND_APP_ADJ;
17453            schedGroup = Process.THREAD_GROUP_DEFAULT;
17454            app.adjType = "top-activity";
17455            foregroundActivities = true;
17456            procState = PROCESS_STATE_TOP;
17457        } else if (app.instrumentationClass != null) {
17458            // Don't want to kill running instrumentation.
17459            adj = ProcessList.FOREGROUND_APP_ADJ;
17460            schedGroup = Process.THREAD_GROUP_DEFAULT;
17461            app.adjType = "instrumentation";
17462            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17463        } else if ((queue = isReceivingBroadcast(app)) != null) {
17464            // An app that is currently receiving a broadcast also
17465            // counts as being in the foreground for OOM killer purposes.
17466            // It's placed in a sched group based on the nature of the
17467            // broadcast as reflected by which queue it's active in.
17468            adj = ProcessList.FOREGROUND_APP_ADJ;
17469            schedGroup = (queue == mFgBroadcastQueue)
17470                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17471            app.adjType = "broadcast";
17472            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17473        } else if (app.executingServices.size() > 0) {
17474            // An app that is currently executing a service callback also
17475            // counts as being in the foreground.
17476            adj = ProcessList.FOREGROUND_APP_ADJ;
17477            schedGroup = app.execServicesFg ?
17478                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17479            app.adjType = "exec-service";
17480            procState = ActivityManager.PROCESS_STATE_SERVICE;
17481            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17482        } else {
17483            // As far as we know the process is empty.  We may change our mind later.
17484            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17485            // At this point we don't actually know the adjustment.  Use the cached adj
17486            // value that the caller wants us to.
17487            adj = cachedAdj;
17488            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17489            app.cached = true;
17490            app.empty = true;
17491            app.adjType = "cch-empty";
17492        }
17493
17494        // Examine all activities if not already foreground.
17495        if (!foregroundActivities && activitiesSize > 0) {
17496            for (int j = 0; j < activitiesSize; j++) {
17497                final ActivityRecord r = app.activities.get(j);
17498                if (r.app != app) {
17499                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17500                            + app + "?!? Using " + r.app + " instead.");
17501                    continue;
17502                }
17503                if (r.visible) {
17504                    // App has a visible activity; only upgrade adjustment.
17505                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17506                        adj = ProcessList.VISIBLE_APP_ADJ;
17507                        app.adjType = "visible";
17508                    }
17509                    if (procState > PROCESS_STATE_TOP) {
17510                        procState = PROCESS_STATE_TOP;
17511                    }
17512                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17513                    app.cached = false;
17514                    app.empty = false;
17515                    foregroundActivities = true;
17516                    break;
17517                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17518                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17519                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17520                        app.adjType = "pausing";
17521                    }
17522                    if (procState > PROCESS_STATE_TOP) {
17523                        procState = PROCESS_STATE_TOP;
17524                    }
17525                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17526                    app.cached = false;
17527                    app.empty = false;
17528                    foregroundActivities = true;
17529                } else if (r.state == ActivityState.STOPPING) {
17530                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17531                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17532                        app.adjType = "stopping";
17533                    }
17534                    // For the process state, we will at this point consider the
17535                    // process to be cached.  It will be cached either as an activity
17536                    // or empty depending on whether the activity is finishing.  We do
17537                    // this so that we can treat the process as cached for purposes of
17538                    // memory trimming (determing current memory level, trim command to
17539                    // send to process) since there can be an arbitrary number of stopping
17540                    // processes and they should soon all go into the cached state.
17541                    if (!r.finishing) {
17542                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17543                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17544                        }
17545                    }
17546                    app.cached = false;
17547                    app.empty = false;
17548                    foregroundActivities = true;
17549                } else {
17550                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17551                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17552                        app.adjType = "cch-act";
17553                    }
17554                }
17555            }
17556        }
17557
17558        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17559            if (app.foregroundServices) {
17560                // The user is aware of this app, so make it visible.
17561                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17562                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17563                app.cached = false;
17564                app.adjType = "fg-service";
17565                schedGroup = Process.THREAD_GROUP_DEFAULT;
17566            } else if (app.forcingToForeground != null) {
17567                // The user is aware of this app, so make it visible.
17568                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17569                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17570                app.cached = false;
17571                app.adjType = "force-fg";
17572                app.adjSource = app.forcingToForeground;
17573                schedGroup = Process.THREAD_GROUP_DEFAULT;
17574            }
17575        }
17576
17577        if (app == mHeavyWeightProcess) {
17578            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17579                // We don't want to kill the current heavy-weight process.
17580                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17581                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17582                app.cached = false;
17583                app.adjType = "heavy";
17584            }
17585            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17586                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17587            }
17588        }
17589
17590        if (app == mHomeProcess) {
17591            if (adj > ProcessList.HOME_APP_ADJ) {
17592                // This process is hosting what we currently consider to be the
17593                // home app, so we don't want to let it go into the background.
17594                adj = ProcessList.HOME_APP_ADJ;
17595                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17596                app.cached = false;
17597                app.adjType = "home";
17598            }
17599            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17600                procState = ActivityManager.PROCESS_STATE_HOME;
17601            }
17602        }
17603
17604        if (app == mPreviousProcess && app.activities.size() > 0) {
17605            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17606                // This was the previous process that showed UI to the user.
17607                // We want to try to keep it around more aggressively, to give
17608                // a good experience around switching between two apps.
17609                adj = ProcessList.PREVIOUS_APP_ADJ;
17610                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17611                app.cached = false;
17612                app.adjType = "previous";
17613            }
17614            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17615                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17616            }
17617        }
17618
17619        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17620                + " reason=" + app.adjType);
17621
17622        // By default, we use the computed adjustment.  It may be changed if
17623        // there are applications dependent on our services or providers, but
17624        // this gives us a baseline and makes sure we don't get into an
17625        // infinite recursion.
17626        app.adjSeq = mAdjSeq;
17627        app.curRawAdj = adj;
17628        app.hasStartedServices = false;
17629
17630        if (mBackupTarget != null && app == mBackupTarget.app) {
17631            // If possible we want to avoid killing apps while they're being backed up
17632            if (adj > ProcessList.BACKUP_APP_ADJ) {
17633                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17634                adj = ProcessList.BACKUP_APP_ADJ;
17635                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17636                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17637                }
17638                app.adjType = "backup";
17639                app.cached = false;
17640            }
17641            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17642                procState = ActivityManager.PROCESS_STATE_BACKUP;
17643            }
17644        }
17645
17646        boolean mayBeTop = false;
17647
17648        for (int is = app.services.size()-1;
17649                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17650                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17651                        || procState > ActivityManager.PROCESS_STATE_TOP);
17652                is--) {
17653            ServiceRecord s = app.services.valueAt(is);
17654            if (s.startRequested) {
17655                app.hasStartedServices = true;
17656                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17657                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17658                }
17659                if (app.hasShownUi && app != mHomeProcess) {
17660                    // If this process has shown some UI, let it immediately
17661                    // go to the LRU list because it may be pretty heavy with
17662                    // UI stuff.  We'll tag it with a label just to help
17663                    // debug and understand what is going on.
17664                    if (adj > ProcessList.SERVICE_ADJ) {
17665                        app.adjType = "cch-started-ui-services";
17666                    }
17667                } else {
17668                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17669                        // This service has seen some activity within
17670                        // recent memory, so we will keep its process ahead
17671                        // of the background processes.
17672                        if (adj > ProcessList.SERVICE_ADJ) {
17673                            adj = ProcessList.SERVICE_ADJ;
17674                            app.adjType = "started-services";
17675                            app.cached = false;
17676                        }
17677                    }
17678                    // If we have let the service slide into the background
17679                    // state, still have some text describing what it is doing
17680                    // even though the service no longer has an impact.
17681                    if (adj > ProcessList.SERVICE_ADJ) {
17682                        app.adjType = "cch-started-services";
17683                    }
17684                }
17685            }
17686            for (int conni = s.connections.size()-1;
17687                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17688                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17689                            || procState > ActivityManager.PROCESS_STATE_TOP);
17690                    conni--) {
17691                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17692                for (int i = 0;
17693                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17694                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17695                                || procState > ActivityManager.PROCESS_STATE_TOP);
17696                        i++) {
17697                    // XXX should compute this based on the max of
17698                    // all connected clients.
17699                    ConnectionRecord cr = clist.get(i);
17700                    if (cr.binding.client == app) {
17701                        // Binding to ourself is not interesting.
17702                        continue;
17703                    }
17704                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17705                        ProcessRecord client = cr.binding.client;
17706                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17707                                TOP_APP, doingAll, now);
17708                        int clientProcState = client.curProcState;
17709                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17710                            // If the other app is cached for any reason, for purposes here
17711                            // we are going to consider it empty.  The specific cached state
17712                            // doesn't propagate except under certain conditions.
17713                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17714                        }
17715                        String adjType = null;
17716                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17717                            // Not doing bind OOM management, so treat
17718                            // this guy more like a started service.
17719                            if (app.hasShownUi && app != mHomeProcess) {
17720                                // If this process has shown some UI, let it immediately
17721                                // go to the LRU list because it may be pretty heavy with
17722                                // UI stuff.  We'll tag it with a label just to help
17723                                // debug and understand what is going on.
17724                                if (adj > clientAdj) {
17725                                    adjType = "cch-bound-ui-services";
17726                                }
17727                                app.cached = false;
17728                                clientAdj = adj;
17729                                clientProcState = procState;
17730                            } else {
17731                                if (now >= (s.lastActivity
17732                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17733                                    // This service has not seen activity within
17734                                    // recent memory, so allow it to drop to the
17735                                    // LRU list if there is no other reason to keep
17736                                    // it around.  We'll also tag it with a label just
17737                                    // to help debug and undertand what is going on.
17738                                    if (adj > clientAdj) {
17739                                        adjType = "cch-bound-services";
17740                                    }
17741                                    clientAdj = adj;
17742                                }
17743                            }
17744                        }
17745                        if (adj > clientAdj) {
17746                            // If this process has recently shown UI, and
17747                            // the process that is binding to it is less
17748                            // important than being visible, then we don't
17749                            // care about the binding as much as we care
17750                            // about letting this process get into the LRU
17751                            // list to be killed and restarted if needed for
17752                            // memory.
17753                            if (app.hasShownUi && app != mHomeProcess
17754                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17755                                adjType = "cch-bound-ui-services";
17756                            } else {
17757                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17758                                        |Context.BIND_IMPORTANT)) != 0) {
17759                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17760                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17761                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17762                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17763                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17764                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17765                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17766                                    adj = clientAdj;
17767                                } else {
17768                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17769                                        adj = ProcessList.VISIBLE_APP_ADJ;
17770                                    }
17771                                }
17772                                if (!client.cached) {
17773                                    app.cached = false;
17774                                }
17775                                adjType = "service";
17776                            }
17777                        }
17778                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17779                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17780                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17781                            }
17782                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17783                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17784                                    // Special handling of clients who are in the top state.
17785                                    // We *may* want to consider this process to be in the
17786                                    // top state as well, but only if there is not another
17787                                    // reason for it to be running.  Being on the top is a
17788                                    // special state, meaning you are specifically running
17789                                    // for the current top app.  If the process is already
17790                                    // running in the background for some other reason, it
17791                                    // is more important to continue considering it to be
17792                                    // in the background state.
17793                                    mayBeTop = true;
17794                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17795                                } else {
17796                                    // Special handling for above-top states (persistent
17797                                    // processes).  These should not bring the current process
17798                                    // into the top state, since they are not on top.  Instead
17799                                    // give them the best state after that.
17800                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
17801                                        clientProcState =
17802                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17803                                    } else if (mWakefulness
17804                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
17805                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
17806                                                    != 0) {
17807                                        clientProcState =
17808                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17809                                    } else {
17810                                        clientProcState =
17811                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17812                                    }
17813                                }
17814                            }
17815                        } else {
17816                            if (clientProcState <
17817                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17818                                clientProcState =
17819                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17820                            }
17821                        }
17822                        if (procState > clientProcState) {
17823                            procState = clientProcState;
17824                        }
17825                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17826                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17827                            app.pendingUiClean = true;
17828                        }
17829                        if (adjType != null) {
17830                            app.adjType = adjType;
17831                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17832                                    .REASON_SERVICE_IN_USE;
17833                            app.adjSource = cr.binding.client;
17834                            app.adjSourceProcState = clientProcState;
17835                            app.adjTarget = s.name;
17836                        }
17837                    }
17838                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17839                        app.treatLikeActivity = true;
17840                    }
17841                    final ActivityRecord a = cr.activity;
17842                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17843                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17844                                (a.visible || a.state == ActivityState.RESUMED
17845                                 || a.state == ActivityState.PAUSING)) {
17846                            adj = ProcessList.FOREGROUND_APP_ADJ;
17847                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17848                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17849                            }
17850                            app.cached = false;
17851                            app.adjType = "service";
17852                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17853                                    .REASON_SERVICE_IN_USE;
17854                            app.adjSource = a;
17855                            app.adjSourceProcState = procState;
17856                            app.adjTarget = s.name;
17857                        }
17858                    }
17859                }
17860            }
17861        }
17862
17863        for (int provi = app.pubProviders.size()-1;
17864                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17865                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17866                        || procState > ActivityManager.PROCESS_STATE_TOP);
17867                provi--) {
17868            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17869            for (int i = cpr.connections.size()-1;
17870                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17871                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17872                            || procState > ActivityManager.PROCESS_STATE_TOP);
17873                    i--) {
17874                ContentProviderConnection conn = cpr.connections.get(i);
17875                ProcessRecord client = conn.client;
17876                if (client == app) {
17877                    // Being our own client is not interesting.
17878                    continue;
17879                }
17880                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17881                int clientProcState = client.curProcState;
17882                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17883                    // If the other app is cached for any reason, for purposes here
17884                    // we are going to consider it empty.
17885                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17886                }
17887                if (adj > clientAdj) {
17888                    if (app.hasShownUi && app != mHomeProcess
17889                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17890                        app.adjType = "cch-ui-provider";
17891                    } else {
17892                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17893                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17894                        app.adjType = "provider";
17895                    }
17896                    app.cached &= client.cached;
17897                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17898                            .REASON_PROVIDER_IN_USE;
17899                    app.adjSource = client;
17900                    app.adjSourceProcState = clientProcState;
17901                    app.adjTarget = cpr.name;
17902                }
17903                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17904                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17905                        // Special handling of clients who are in the top state.
17906                        // We *may* want to consider this process to be in the
17907                        // top state as well, but only if there is not another
17908                        // reason for it to be running.  Being on the top is a
17909                        // special state, meaning you are specifically running
17910                        // for the current top app.  If the process is already
17911                        // running in the background for some other reason, it
17912                        // is more important to continue considering it to be
17913                        // in the background state.
17914                        mayBeTop = true;
17915                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17916                    } else {
17917                        // Special handling for above-top states (persistent
17918                        // processes).  These should not bring the current process
17919                        // into the top state, since they are not on top.  Instead
17920                        // give them the best state after that.
17921                        clientProcState =
17922                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17923                    }
17924                }
17925                if (procState > clientProcState) {
17926                    procState = clientProcState;
17927                }
17928                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17929                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17930                }
17931            }
17932            // If the provider has external (non-framework) process
17933            // dependencies, ensure that its adjustment is at least
17934            // FOREGROUND_APP_ADJ.
17935            if (cpr.hasExternalProcessHandles()) {
17936                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17937                    adj = ProcessList.FOREGROUND_APP_ADJ;
17938                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17939                    app.cached = false;
17940                    app.adjType = "provider";
17941                    app.adjTarget = cpr.name;
17942                }
17943                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17944                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17945                }
17946            }
17947        }
17948
17949        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17950            // A client of one of our services or providers is in the top state.  We
17951            // *may* want to be in the top state, but not if we are already running in
17952            // the background for some other reason.  For the decision here, we are going
17953            // to pick out a few specific states that we want to remain in when a client
17954            // is top (states that tend to be longer-term) and otherwise allow it to go
17955            // to the top state.
17956            switch (procState) {
17957                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17958                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17959                case ActivityManager.PROCESS_STATE_SERVICE:
17960                    // These all are longer-term states, so pull them up to the top
17961                    // of the background states, but not all the way to the top state.
17962                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17963                    break;
17964                default:
17965                    // Otherwise, top is a better choice, so take it.
17966                    procState = ActivityManager.PROCESS_STATE_TOP;
17967                    break;
17968            }
17969        }
17970
17971        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17972            if (app.hasClientActivities) {
17973                // This is a cached process, but with client activities.  Mark it so.
17974                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17975                app.adjType = "cch-client-act";
17976            } else if (app.treatLikeActivity) {
17977                // This is a cached process, but somebody wants us to treat it like it has
17978                // an activity, okay!
17979                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17980                app.adjType = "cch-as-act";
17981            }
17982        }
17983
17984        if (adj == ProcessList.SERVICE_ADJ) {
17985            if (doingAll) {
17986                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17987                mNewNumServiceProcs++;
17988                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17989                if (!app.serviceb) {
17990                    // This service isn't far enough down on the LRU list to
17991                    // normally be a B service, but if we are low on RAM and it
17992                    // is large we want to force it down since we would prefer to
17993                    // keep launcher over it.
17994                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17995                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17996                        app.serviceHighRam = true;
17997                        app.serviceb = true;
17998                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17999                    } else {
18000                        mNewNumAServiceProcs++;
18001                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18002                    }
18003                } else {
18004                    app.serviceHighRam = false;
18005                }
18006            }
18007            if (app.serviceb) {
18008                adj = ProcessList.SERVICE_B_ADJ;
18009            }
18010        }
18011
18012        app.curRawAdj = adj;
18013
18014        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18015        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18016        if (adj > app.maxAdj) {
18017            adj = app.maxAdj;
18018            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18019                schedGroup = Process.THREAD_GROUP_DEFAULT;
18020            }
18021        }
18022
18023        // Do final modification to adj.  Everything we do between here and applying
18024        // the final setAdj must be done in this function, because we will also use
18025        // it when computing the final cached adj later.  Note that we don't need to
18026        // worry about this for max adj above, since max adj will always be used to
18027        // keep it out of the cached vaues.
18028        app.curAdj = app.modifyRawOomAdj(adj);
18029        app.curSchedGroup = schedGroup;
18030        app.curProcState = procState;
18031        app.foregroundActivities = foregroundActivities;
18032
18033        return app.curRawAdj;
18034    }
18035
18036    /**
18037     * Record new PSS sample for a process.
18038     */
18039    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18040        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18041        proc.lastPssTime = now;
18042        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18043        if (DEBUG_PSS) Slog.d(TAG_PSS,
18044                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18045                + " state=" + ProcessList.makeProcStateString(procState));
18046        if (proc.initialIdlePss == 0) {
18047            proc.initialIdlePss = pss;
18048        }
18049        proc.lastPss = pss;
18050        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18051            proc.lastCachedPss = pss;
18052        }
18053
18054        final SparseArray<Pair<Long, String>> watchUids
18055                = mMemWatchProcesses.getMap().get(proc.processName);
18056        Long check = null;
18057        if (watchUids != null) {
18058            Pair<Long, String> val = watchUids.get(proc.uid);
18059            if (val == null) {
18060                val = watchUids.get(0);
18061            }
18062            if (val != null) {
18063                check = val.first;
18064            }
18065        }
18066        if (check != null) {
18067            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18068                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18069                if (!isDebuggable) {
18070                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18071                        isDebuggable = true;
18072                    }
18073                }
18074                if (isDebuggable) {
18075                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18076                    final ProcessRecord myProc = proc;
18077                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18078                    mMemWatchDumpProcName = proc.processName;
18079                    mMemWatchDumpFile = heapdumpFile.toString();
18080                    mMemWatchDumpPid = proc.pid;
18081                    mMemWatchDumpUid = proc.uid;
18082                    BackgroundThread.getHandler().post(new Runnable() {
18083                        @Override
18084                        public void run() {
18085                            revokeUriPermission(ActivityThread.currentActivityThread()
18086                                            .getApplicationThread(),
18087                                    DumpHeapActivity.JAVA_URI,
18088                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18089                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18090                                    UserHandle.myUserId());
18091                            ParcelFileDescriptor fd = null;
18092                            try {
18093                                heapdumpFile.delete();
18094                                fd = ParcelFileDescriptor.open(heapdumpFile,
18095                                        ParcelFileDescriptor.MODE_CREATE |
18096                                                ParcelFileDescriptor.MODE_TRUNCATE |
18097                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18098                                                ParcelFileDescriptor.MODE_APPEND);
18099                                IApplicationThread thread = myProc.thread;
18100                                if (thread != null) {
18101                                    try {
18102                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18103                                                "Requesting dump heap from "
18104                                                + myProc + " to " + heapdumpFile);
18105                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18106                                    } catch (RemoteException e) {
18107                                    }
18108                                }
18109                            } catch (FileNotFoundException e) {
18110                                e.printStackTrace();
18111                            } finally {
18112                                if (fd != null) {
18113                                    try {
18114                                        fd.close();
18115                                    } catch (IOException e) {
18116                                    }
18117                                }
18118                            }
18119                        }
18120                    });
18121                } else {
18122                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18123                            + ", but debugging not enabled");
18124                }
18125            }
18126        }
18127    }
18128
18129    /**
18130     * Schedule PSS collection of a process.
18131     */
18132    void requestPssLocked(ProcessRecord proc, int procState) {
18133        if (mPendingPssProcesses.contains(proc)) {
18134            return;
18135        }
18136        if (mPendingPssProcesses.size() == 0) {
18137            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18138        }
18139        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18140        proc.pssProcState = procState;
18141        mPendingPssProcesses.add(proc);
18142    }
18143
18144    /**
18145     * Schedule PSS collection of all processes.
18146     */
18147    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18148        if (!always) {
18149            if (now < (mLastFullPssTime +
18150                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18151                return;
18152            }
18153        }
18154        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18155        mLastFullPssTime = now;
18156        mFullPssPending = true;
18157        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18158        mPendingPssProcesses.clear();
18159        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18160            ProcessRecord app = mLruProcesses.get(i);
18161            if (app.thread == null
18162                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18163                continue;
18164            }
18165            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18166                app.pssProcState = app.setProcState;
18167                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18168                        mTestPssMode, isSleeping(), now);
18169                mPendingPssProcesses.add(app);
18170            }
18171        }
18172        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18173    }
18174
18175    public void setTestPssMode(boolean enabled) {
18176        synchronized (this) {
18177            mTestPssMode = enabled;
18178            if (enabled) {
18179                // Whenever we enable the mode, we want to take a snapshot all of current
18180                // process mem use.
18181                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18182            }
18183        }
18184    }
18185
18186    /**
18187     * Ask a given process to GC right now.
18188     */
18189    final void performAppGcLocked(ProcessRecord app) {
18190        try {
18191            app.lastRequestedGc = SystemClock.uptimeMillis();
18192            if (app.thread != null) {
18193                if (app.reportLowMemory) {
18194                    app.reportLowMemory = false;
18195                    app.thread.scheduleLowMemory();
18196                } else {
18197                    app.thread.processInBackground();
18198                }
18199            }
18200        } catch (Exception e) {
18201            // whatever.
18202        }
18203    }
18204
18205    /**
18206     * Returns true if things are idle enough to perform GCs.
18207     */
18208    private final boolean canGcNowLocked() {
18209        boolean processingBroadcasts = false;
18210        for (BroadcastQueue q : mBroadcastQueues) {
18211            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18212                processingBroadcasts = true;
18213            }
18214        }
18215        return !processingBroadcasts
18216                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18217    }
18218
18219    /**
18220     * Perform GCs on all processes that are waiting for it, but only
18221     * if things are idle.
18222     */
18223    final void performAppGcsLocked() {
18224        final int N = mProcessesToGc.size();
18225        if (N <= 0) {
18226            return;
18227        }
18228        if (canGcNowLocked()) {
18229            while (mProcessesToGc.size() > 0) {
18230                ProcessRecord proc = mProcessesToGc.remove(0);
18231                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18232                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18233                            <= SystemClock.uptimeMillis()) {
18234                        // To avoid spamming the system, we will GC processes one
18235                        // at a time, waiting a few seconds between each.
18236                        performAppGcLocked(proc);
18237                        scheduleAppGcsLocked();
18238                        return;
18239                    } else {
18240                        // It hasn't been long enough since we last GCed this
18241                        // process...  put it in the list to wait for its time.
18242                        addProcessToGcListLocked(proc);
18243                        break;
18244                    }
18245                }
18246            }
18247
18248            scheduleAppGcsLocked();
18249        }
18250    }
18251
18252    /**
18253     * If all looks good, perform GCs on all processes waiting for them.
18254     */
18255    final void performAppGcsIfAppropriateLocked() {
18256        if (canGcNowLocked()) {
18257            performAppGcsLocked();
18258            return;
18259        }
18260        // Still not idle, wait some more.
18261        scheduleAppGcsLocked();
18262    }
18263
18264    /**
18265     * Schedule the execution of all pending app GCs.
18266     */
18267    final void scheduleAppGcsLocked() {
18268        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18269
18270        if (mProcessesToGc.size() > 0) {
18271            // Schedule a GC for the time to the next process.
18272            ProcessRecord proc = mProcessesToGc.get(0);
18273            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18274
18275            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18276            long now = SystemClock.uptimeMillis();
18277            if (when < (now+GC_TIMEOUT)) {
18278                when = now + GC_TIMEOUT;
18279            }
18280            mHandler.sendMessageAtTime(msg, when);
18281        }
18282    }
18283
18284    /**
18285     * Add a process to the array of processes waiting to be GCed.  Keeps the
18286     * list in sorted order by the last GC time.  The process can't already be
18287     * on the list.
18288     */
18289    final void addProcessToGcListLocked(ProcessRecord proc) {
18290        boolean added = false;
18291        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18292            if (mProcessesToGc.get(i).lastRequestedGc <
18293                    proc.lastRequestedGc) {
18294                added = true;
18295                mProcessesToGc.add(i+1, proc);
18296                break;
18297            }
18298        }
18299        if (!added) {
18300            mProcessesToGc.add(0, proc);
18301        }
18302    }
18303
18304    /**
18305     * Set up to ask a process to GC itself.  This will either do it
18306     * immediately, or put it on the list of processes to gc the next
18307     * time things are idle.
18308     */
18309    final void scheduleAppGcLocked(ProcessRecord app) {
18310        long now = SystemClock.uptimeMillis();
18311        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18312            return;
18313        }
18314        if (!mProcessesToGc.contains(app)) {
18315            addProcessToGcListLocked(app);
18316            scheduleAppGcsLocked();
18317        }
18318    }
18319
18320    final void checkExcessivePowerUsageLocked(boolean doKills) {
18321        updateCpuStatsNow();
18322
18323        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18324        boolean doWakeKills = doKills;
18325        boolean doCpuKills = doKills;
18326        if (mLastPowerCheckRealtime == 0) {
18327            doWakeKills = false;
18328        }
18329        if (mLastPowerCheckUptime == 0) {
18330            doCpuKills = false;
18331        }
18332        if (stats.isScreenOn()) {
18333            doWakeKills = false;
18334        }
18335        final long curRealtime = SystemClock.elapsedRealtime();
18336        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18337        final long curUptime = SystemClock.uptimeMillis();
18338        final long uptimeSince = curUptime - mLastPowerCheckUptime;
18339        mLastPowerCheckRealtime = curRealtime;
18340        mLastPowerCheckUptime = curUptime;
18341        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18342            doWakeKills = false;
18343        }
18344        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18345            doCpuKills = false;
18346        }
18347        int i = mLruProcesses.size();
18348        while (i > 0) {
18349            i--;
18350            ProcessRecord app = mLruProcesses.get(i);
18351            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18352                long wtime;
18353                synchronized (stats) {
18354                    wtime = stats.getProcessWakeTime(app.info.uid,
18355                            app.pid, curRealtime);
18356                }
18357                long wtimeUsed = wtime - app.lastWakeTime;
18358                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18359                if (DEBUG_POWER) {
18360                    StringBuilder sb = new StringBuilder(128);
18361                    sb.append("Wake for ");
18362                    app.toShortString(sb);
18363                    sb.append(": over ");
18364                    TimeUtils.formatDuration(realtimeSince, sb);
18365                    sb.append(" used ");
18366                    TimeUtils.formatDuration(wtimeUsed, sb);
18367                    sb.append(" (");
18368                    sb.append((wtimeUsed*100)/realtimeSince);
18369                    sb.append("%)");
18370                    Slog.i(TAG_POWER, sb.toString());
18371                    sb.setLength(0);
18372                    sb.append("CPU for ");
18373                    app.toShortString(sb);
18374                    sb.append(": over ");
18375                    TimeUtils.formatDuration(uptimeSince, sb);
18376                    sb.append(" used ");
18377                    TimeUtils.formatDuration(cputimeUsed, sb);
18378                    sb.append(" (");
18379                    sb.append((cputimeUsed*100)/uptimeSince);
18380                    sb.append("%)");
18381                    Slog.i(TAG_POWER, sb.toString());
18382                }
18383                // If a process has held a wake lock for more
18384                // than 50% of the time during this period,
18385                // that sounds bad.  Kill!
18386                if (doWakeKills && realtimeSince > 0
18387                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
18388                    synchronized (stats) {
18389                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18390                                realtimeSince, wtimeUsed);
18391                    }
18392                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18393                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18394                } else if (doCpuKills && uptimeSince > 0
18395                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
18396                    synchronized (stats) {
18397                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18398                                uptimeSince, cputimeUsed);
18399                    }
18400                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18401                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18402                } else {
18403                    app.lastWakeTime = wtime;
18404                    app.lastCpuTime = app.curCpuTime;
18405                }
18406            }
18407        }
18408    }
18409
18410    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
18411        boolean success = true;
18412
18413        if (app.curRawAdj != app.setRawAdj) {
18414            app.setRawAdj = app.curRawAdj;
18415        }
18416
18417        int changes = 0;
18418
18419        if (app.curAdj != app.setAdj) {
18420            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18421            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18422                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18423                    + app.adjType);
18424            app.setAdj = app.curAdj;
18425        }
18426
18427        if (app.setSchedGroup != app.curSchedGroup) {
18428            app.setSchedGroup = app.curSchedGroup;
18429            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18430                    "Setting process group of " + app.processName
18431                    + " to " + app.curSchedGroup);
18432            if (app.waitingToKill != null && app.curReceiver == null
18433                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18434                app.kill(app.waitingToKill, true);
18435                success = false;
18436            } else {
18437                if (true) {
18438                    long oldId = Binder.clearCallingIdentity();
18439                    try {
18440                        Process.setProcessGroup(app.pid, app.curSchedGroup);
18441                    } catch (Exception e) {
18442                        Slog.w(TAG, "Failed setting process group of " + app.pid
18443                                + " to " + app.curSchedGroup);
18444                        e.printStackTrace();
18445                    } finally {
18446                        Binder.restoreCallingIdentity(oldId);
18447                    }
18448                } else {
18449                    if (app.thread != null) {
18450                        try {
18451                            app.thread.setSchedulingGroup(app.curSchedGroup);
18452                        } catch (RemoteException e) {
18453                        }
18454                    }
18455                }
18456                Process.setSwappiness(app.pid,
18457                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18458            }
18459        }
18460        if (app.repForegroundActivities != app.foregroundActivities) {
18461            app.repForegroundActivities = app.foregroundActivities;
18462            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18463        }
18464        if (app.repProcState != app.curProcState) {
18465            app.repProcState = app.curProcState;
18466            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18467            if (app.thread != null) {
18468                try {
18469                    if (false) {
18470                        //RuntimeException h = new RuntimeException("here");
18471                        Slog.i(TAG, "Sending new process state " + app.repProcState
18472                                + " to " + app /*, h*/);
18473                    }
18474                    app.thread.setProcessState(app.repProcState);
18475                } catch (RemoteException e) {
18476                }
18477            }
18478        }
18479        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18480                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18481            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18482                // Experimental code to more aggressively collect pss while
18483                // running test...  the problem is that this tends to collect
18484                // the data right when a process is transitioning between process
18485                // states, which well tend to give noisy data.
18486                long start = SystemClock.uptimeMillis();
18487                long pss = Debug.getPss(app.pid, mTmpLong, null);
18488                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18489                mPendingPssProcesses.remove(app);
18490                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18491                        + " to " + app.curProcState + ": "
18492                        + (SystemClock.uptimeMillis()-start) + "ms");
18493            }
18494            app.lastStateTime = now;
18495            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18496                    mTestPssMode, isSleeping(), now);
18497            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18498                    + ProcessList.makeProcStateString(app.setProcState) + " to "
18499                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18500                    + (app.nextPssTime-now) + ": " + app);
18501        } else {
18502            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18503                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18504                    mTestPssMode)))) {
18505                requestPssLocked(app, app.setProcState);
18506                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18507                        mTestPssMode, isSleeping(), now);
18508            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18509                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18510        }
18511        if (app.setProcState != app.curProcState) {
18512            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18513                    "Proc state change of " + app.processName
18514                    + " to " + app.curProcState);
18515            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18516            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18517            if (setImportant && !curImportant) {
18518                // This app is no longer something we consider important enough to allow to
18519                // use arbitrary amounts of battery power.  Note
18520                // its current wake lock time to later know to kill it if
18521                // it is not behaving well.
18522                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18523                synchronized (stats) {
18524                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18525                            app.pid, SystemClock.elapsedRealtime());
18526                }
18527                app.lastCpuTime = app.curCpuTime;
18528
18529            }
18530            // Inform UsageStats of important process state change
18531            // Must be called before updating setProcState
18532            maybeUpdateUsageStatsLocked(app);
18533
18534            app.setProcState = app.curProcState;
18535            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18536                app.notCachedSinceIdle = false;
18537            }
18538            if (!doingAll) {
18539                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18540            } else {
18541                app.procStateChanged = true;
18542            }
18543        }
18544
18545        if (changes != 0) {
18546            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18547                    "Changes in " + app + ": " + changes);
18548            int i = mPendingProcessChanges.size()-1;
18549            ProcessChangeItem item = null;
18550            while (i >= 0) {
18551                item = mPendingProcessChanges.get(i);
18552                if (item.pid == app.pid) {
18553                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18554                            "Re-using existing item: " + item);
18555                    break;
18556                }
18557                i--;
18558            }
18559            if (i < 0) {
18560                // No existing item in pending changes; need a new one.
18561                final int NA = mAvailProcessChanges.size();
18562                if (NA > 0) {
18563                    item = mAvailProcessChanges.remove(NA-1);
18564                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18565                            "Retrieving available item: " + item);
18566                } else {
18567                    item = new ProcessChangeItem();
18568                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18569                            "Allocating new item: " + item);
18570                }
18571                item.changes = 0;
18572                item.pid = app.pid;
18573                item.uid = app.info.uid;
18574                if (mPendingProcessChanges.size() == 0) {
18575                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18576                            "*** Enqueueing dispatch processes changed!");
18577                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18578                }
18579                mPendingProcessChanges.add(item);
18580            }
18581            item.changes |= changes;
18582            item.processState = app.repProcState;
18583            item.foregroundActivities = app.repForegroundActivities;
18584            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18585                    "Item " + Integer.toHexString(System.identityHashCode(item))
18586                    + " " + app.toShortString() + ": changes=" + item.changes
18587                    + " procState=" + item.processState
18588                    + " foreground=" + item.foregroundActivities
18589                    + " type=" + app.adjType + " source=" + app.adjSource
18590                    + " target=" + app.adjTarget);
18591        }
18592
18593        return success;
18594    }
18595
18596    private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18597        if (uidRec.pendingChange == null) {
18598            if (mPendingUidChanges.size() == 0) {
18599                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18600                        "*** Enqueueing dispatch uid changed!");
18601                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18602            }
18603            final int NA = mAvailUidChanges.size();
18604            if (NA > 0) {
18605                uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18606                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18607                        "Retrieving available item: " + uidRec.pendingChange);
18608            } else {
18609                uidRec.pendingChange = new UidRecord.ChangeItem();
18610                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18611                        "Allocating new item: " + uidRec.pendingChange);
18612            }
18613            uidRec.pendingChange.uidRecord = uidRec;
18614            uidRec.pendingChange.uid = uidRec.uid;
18615            mPendingUidChanges.add(uidRec.pendingChange);
18616        }
18617        uidRec.pendingChange.gone = gone;
18618        uidRec.pendingChange.processState = uidRec.setProcState;
18619    }
18620
18621    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18622            String authority) {
18623        if (app == null) return;
18624        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18625            UserState userState = mStartedUsers.get(app.userId);
18626            if (userState == null) return;
18627            final long now = SystemClock.elapsedRealtime();
18628            Long lastReported = userState.mProviderLastReportedFg.get(authority);
18629            if (lastReported == null || lastReported < now - 60 * 1000L) {
18630                mUsageStatsService.reportContentProviderUsage(
18631                        authority, providerPkgName, app.userId);
18632                userState.mProviderLastReportedFg.put(authority, now);
18633            }
18634        }
18635    }
18636
18637    private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
18638        if (DEBUG_USAGE_STATS) {
18639            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18640                    + "] state changes: old = " + app.setProcState + ", new = "
18641                    + app.curProcState);
18642        }
18643        if (mUsageStatsService == null) {
18644            return;
18645        }
18646        boolean isInteraction;
18647        // To avoid some abuse patterns, we are going to be careful about what we consider
18648        // to be an app interaction.  Being the top activity doesn't count while the display
18649        // is sleeping, nor do short foreground services.
18650        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18651            isInteraction = true;
18652            app.fgInteractionTime = 0;
18653        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18654            final long now = SystemClock.elapsedRealtime();
18655            if (app.fgInteractionTime == 0) {
18656                app.fgInteractionTime = now;
18657                isInteraction = false;
18658            } else {
18659                isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18660            }
18661        } else {
18662            isInteraction = app.curProcState
18663                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18664            app.fgInteractionTime = 0;
18665        }
18666        if (isInteraction && !app.reportedInteraction) {
18667            String[] packages = app.getPackageList();
18668            if (packages != null) {
18669                for (int i = 0; i < packages.length; i++) {
18670                    mUsageStatsService.reportEvent(packages[i], app.userId,
18671                            UsageEvents.Event.SYSTEM_INTERACTION);
18672                }
18673            }
18674        }
18675        app.reportedInteraction = isInteraction;
18676    }
18677
18678    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18679        if (proc.thread != null) {
18680            if (proc.baseProcessTracker != null) {
18681                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18682            }
18683            if (proc.repProcState >= 0) {
18684                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18685                        proc.repProcState);
18686            }
18687        }
18688    }
18689
18690    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18691            ProcessRecord TOP_APP, boolean doingAll, long now) {
18692        if (app.thread == null) {
18693            return false;
18694        }
18695
18696        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18697
18698        return applyOomAdjLocked(app, doingAll, now);
18699    }
18700
18701    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18702            boolean oomAdj) {
18703        if (isForeground != proc.foregroundServices) {
18704            proc.foregroundServices = isForeground;
18705            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18706                    proc.info.uid);
18707            if (isForeground) {
18708                if (curProcs == null) {
18709                    curProcs = new ArrayList<ProcessRecord>();
18710                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18711                }
18712                if (!curProcs.contains(proc)) {
18713                    curProcs.add(proc);
18714                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18715                            proc.info.packageName, proc.info.uid);
18716                }
18717            } else {
18718                if (curProcs != null) {
18719                    if (curProcs.remove(proc)) {
18720                        mBatteryStatsService.noteEvent(
18721                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18722                                proc.info.packageName, proc.info.uid);
18723                        if (curProcs.size() <= 0) {
18724                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18725                        }
18726                    }
18727                }
18728            }
18729            if (oomAdj) {
18730                updateOomAdjLocked();
18731            }
18732        }
18733    }
18734
18735    private final ActivityRecord resumedAppLocked() {
18736        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18737        String pkg;
18738        int uid;
18739        if (act != null) {
18740            pkg = act.packageName;
18741            uid = act.info.applicationInfo.uid;
18742        } else {
18743            pkg = null;
18744            uid = -1;
18745        }
18746        // Has the UID or resumed package name changed?
18747        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18748                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18749            if (mCurResumedPackage != null) {
18750                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18751                        mCurResumedPackage, mCurResumedUid);
18752            }
18753            mCurResumedPackage = pkg;
18754            mCurResumedUid = uid;
18755            if (mCurResumedPackage != null) {
18756                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18757                        mCurResumedPackage, mCurResumedUid);
18758            }
18759        }
18760        return act;
18761    }
18762
18763    final boolean updateOomAdjLocked(ProcessRecord app) {
18764        final ActivityRecord TOP_ACT = resumedAppLocked();
18765        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18766        final boolean wasCached = app.cached;
18767
18768        mAdjSeq++;
18769
18770        // This is the desired cached adjusment we want to tell it to use.
18771        // If our app is currently cached, we know it, and that is it.  Otherwise,
18772        // we don't know it yet, and it needs to now be cached we will then
18773        // need to do a complete oom adj.
18774        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18775                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18776        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18777                SystemClock.uptimeMillis());
18778        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18779            // Changed to/from cached state, so apps after it in the LRU
18780            // list may also be changed.
18781            updateOomAdjLocked();
18782        }
18783        return success;
18784    }
18785
18786    final void updateOomAdjLocked() {
18787        final ActivityRecord TOP_ACT = resumedAppLocked();
18788        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18789        final long now = SystemClock.uptimeMillis();
18790        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18791        final int N = mLruProcesses.size();
18792
18793        if (false) {
18794            RuntimeException e = new RuntimeException();
18795            e.fillInStackTrace();
18796            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18797        }
18798
18799        // Reset state in all uid records.
18800        for (int i=mActiveUids.size()-1; i>=0; i--) {
18801            final UidRecord uidRec = mActiveUids.valueAt(i);
18802            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18803                    "Starting update of " + uidRec);
18804            uidRec.reset();
18805        }
18806
18807        mAdjSeq++;
18808        mNewNumServiceProcs = 0;
18809        mNewNumAServiceProcs = 0;
18810
18811        final int emptyProcessLimit;
18812        final int cachedProcessLimit;
18813        if (mProcessLimit <= 0) {
18814            emptyProcessLimit = cachedProcessLimit = 0;
18815        } else if (mProcessLimit == 1) {
18816            emptyProcessLimit = 1;
18817            cachedProcessLimit = 0;
18818        } else {
18819            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18820            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18821        }
18822
18823        // Let's determine how many processes we have running vs.
18824        // how many slots we have for background processes; we may want
18825        // to put multiple processes in a slot of there are enough of
18826        // them.
18827        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18828                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18829        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18830        if (numEmptyProcs > cachedProcessLimit) {
18831            // If there are more empty processes than our limit on cached
18832            // processes, then use the cached process limit for the factor.
18833            // This ensures that the really old empty processes get pushed
18834            // down to the bottom, so if we are running low on memory we will
18835            // have a better chance at keeping around more cached processes
18836            // instead of a gazillion empty processes.
18837            numEmptyProcs = cachedProcessLimit;
18838        }
18839        int emptyFactor = numEmptyProcs/numSlots;
18840        if (emptyFactor < 1) emptyFactor = 1;
18841        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18842        if (cachedFactor < 1) cachedFactor = 1;
18843        int stepCached = 0;
18844        int stepEmpty = 0;
18845        int numCached = 0;
18846        int numEmpty = 0;
18847        int numTrimming = 0;
18848
18849        mNumNonCachedProcs = 0;
18850        mNumCachedHiddenProcs = 0;
18851
18852        // First update the OOM adjustment for each of the
18853        // application processes based on their current state.
18854        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18855        int nextCachedAdj = curCachedAdj+1;
18856        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18857        int nextEmptyAdj = curEmptyAdj+2;
18858        for (int i=N-1; i>=0; i--) {
18859            ProcessRecord app = mLruProcesses.get(i);
18860            if (!app.killedByAm && app.thread != null) {
18861                app.procStateChanged = false;
18862                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18863
18864                // If we haven't yet assigned the final cached adj
18865                // to the process, do that now.
18866                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18867                    switch (app.curProcState) {
18868                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18869                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18870                            // This process is a cached process holding activities...
18871                            // assign it the next cached value for that type, and then
18872                            // step that cached level.
18873                            app.curRawAdj = curCachedAdj;
18874                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18875                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
18876                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18877                                    + ")");
18878                            if (curCachedAdj != nextCachedAdj) {
18879                                stepCached++;
18880                                if (stepCached >= cachedFactor) {
18881                                    stepCached = 0;
18882                                    curCachedAdj = nextCachedAdj;
18883                                    nextCachedAdj += 2;
18884                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18885                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18886                                    }
18887                                }
18888                            }
18889                            break;
18890                        default:
18891                            // For everything else, assign next empty cached process
18892                            // level and bump that up.  Note that this means that
18893                            // long-running services that have dropped down to the
18894                            // cached level will be treated as empty (since their process
18895                            // state is still as a service), which is what we want.
18896                            app.curRawAdj = curEmptyAdj;
18897                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18898                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
18899                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18900                                    + ")");
18901                            if (curEmptyAdj != nextEmptyAdj) {
18902                                stepEmpty++;
18903                                if (stepEmpty >= emptyFactor) {
18904                                    stepEmpty = 0;
18905                                    curEmptyAdj = nextEmptyAdj;
18906                                    nextEmptyAdj += 2;
18907                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18908                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18909                                    }
18910                                }
18911                            }
18912                            break;
18913                    }
18914                }
18915
18916                applyOomAdjLocked(app, true, now);
18917
18918                // Count the number of process types.
18919                switch (app.curProcState) {
18920                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18921                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18922                        mNumCachedHiddenProcs++;
18923                        numCached++;
18924                        if (numCached > cachedProcessLimit) {
18925                            app.kill("cached #" + numCached, true);
18926                        }
18927                        break;
18928                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18929                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18930                                && app.lastActivityTime < oldTime) {
18931                            app.kill("empty for "
18932                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18933                                    / 1000) + "s", true);
18934                        } else {
18935                            numEmpty++;
18936                            if (numEmpty > emptyProcessLimit) {
18937                                app.kill("empty #" + numEmpty, true);
18938                            }
18939                        }
18940                        break;
18941                    default:
18942                        mNumNonCachedProcs++;
18943                        break;
18944                }
18945
18946                if (app.isolated && app.services.size() <= 0) {
18947                    // If this is an isolated process, and there are no
18948                    // services running in it, then the process is no longer
18949                    // needed.  We agressively kill these because we can by
18950                    // definition not re-use the same process again, and it is
18951                    // good to avoid having whatever code was running in them
18952                    // left sitting around after no longer needed.
18953                    app.kill("isolated not needed", true);
18954                } else {
18955                    // Keeping this process, update its uid.
18956                    final UidRecord uidRec = app.uidRecord;
18957                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
18958                        uidRec.curProcState = app.curProcState;
18959                    }
18960                }
18961
18962                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18963                        && !app.killedByAm) {
18964                    numTrimming++;
18965                }
18966            }
18967        }
18968
18969        mNumServiceProcs = mNewNumServiceProcs;
18970
18971        // Now determine the memory trimming level of background processes.
18972        // Unfortunately we need to start at the back of the list to do this
18973        // properly.  We only do this if the number of background apps we
18974        // are managing to keep around is less than half the maximum we desire;
18975        // if we are keeping a good number around, we'll let them use whatever
18976        // memory they want.
18977        final int numCachedAndEmpty = numCached + numEmpty;
18978        int memFactor;
18979        if (numCached <= ProcessList.TRIM_CACHED_APPS
18980                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18981            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18982                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18983            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18984                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18985            } else {
18986                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18987            }
18988        } else {
18989            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18990        }
18991        // We always allow the memory level to go up (better).  We only allow it to go
18992        // down if we are in a state where that is allowed, *and* the total number of processes
18993        // has gone down since last time.
18994        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
18995                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
18996                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
18997        if (memFactor > mLastMemoryLevel) {
18998            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18999                memFactor = mLastMemoryLevel;
19000                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19001            }
19002        }
19003        mLastMemoryLevel = memFactor;
19004        mLastNumProcesses = mLruProcesses.size();
19005        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19006        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19007        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19008            if (mLowRamStartTime == 0) {
19009                mLowRamStartTime = now;
19010            }
19011            int step = 0;
19012            int fgTrimLevel;
19013            switch (memFactor) {
19014                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19015                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19016                    break;
19017                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19018                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19019                    break;
19020                default:
19021                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19022                    break;
19023            }
19024            int factor = numTrimming/3;
19025            int minFactor = 2;
19026            if (mHomeProcess != null) minFactor++;
19027            if (mPreviousProcess != null) minFactor++;
19028            if (factor < minFactor) factor = minFactor;
19029            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19030            for (int i=N-1; i>=0; i--) {
19031                ProcessRecord app = mLruProcesses.get(i);
19032                if (allChanged || app.procStateChanged) {
19033                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19034                    app.procStateChanged = false;
19035                }
19036                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19037                        && !app.killedByAm) {
19038                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19039                        try {
19040                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19041                                    "Trimming memory of " + app.processName + " to " + curLevel);
19042                            app.thread.scheduleTrimMemory(curLevel);
19043                        } catch (RemoteException e) {
19044                        }
19045                        if (false) {
19046                            // For now we won't do this; our memory trimming seems
19047                            // to be good enough at this point that destroying
19048                            // activities causes more harm than good.
19049                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19050                                    && app != mHomeProcess && app != mPreviousProcess) {
19051                                // Need to do this on its own message because the stack may not
19052                                // be in a consistent state at this point.
19053                                // For these apps we will also finish their activities
19054                                // to help them free memory.
19055                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19056                            }
19057                        }
19058                    }
19059                    app.trimMemoryLevel = curLevel;
19060                    step++;
19061                    if (step >= factor) {
19062                        step = 0;
19063                        switch (curLevel) {
19064                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19065                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19066                                break;
19067                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19068                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19069                                break;
19070                        }
19071                    }
19072                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19073                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19074                            && app.thread != null) {
19075                        try {
19076                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19077                                    "Trimming memory of heavy-weight " + app.processName
19078                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19079                            app.thread.scheduleTrimMemory(
19080                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19081                        } catch (RemoteException e) {
19082                        }
19083                    }
19084                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19085                } else {
19086                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19087                            || app.systemNoUi) && app.pendingUiClean) {
19088                        // If this application is now in the background and it
19089                        // had done UI, then give it the special trim level to
19090                        // have it free UI resources.
19091                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19092                        if (app.trimMemoryLevel < level && app.thread != null) {
19093                            try {
19094                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19095                                        "Trimming memory of bg-ui " + app.processName
19096                                        + " to " + level);
19097                                app.thread.scheduleTrimMemory(level);
19098                            } catch (RemoteException e) {
19099                            }
19100                        }
19101                        app.pendingUiClean = false;
19102                    }
19103                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19104                        try {
19105                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19106                                    "Trimming memory of fg " + app.processName
19107                                    + " to " + fgTrimLevel);
19108                            app.thread.scheduleTrimMemory(fgTrimLevel);
19109                        } catch (RemoteException e) {
19110                        }
19111                    }
19112                    app.trimMemoryLevel = fgTrimLevel;
19113                }
19114            }
19115        } else {
19116            if (mLowRamStartTime != 0) {
19117                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19118                mLowRamStartTime = 0;
19119            }
19120            for (int i=N-1; i>=0; i--) {
19121                ProcessRecord app = mLruProcesses.get(i);
19122                if (allChanged || app.procStateChanged) {
19123                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19124                    app.procStateChanged = false;
19125                }
19126                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19127                        || app.systemNoUi) && app.pendingUiClean) {
19128                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19129                            && app.thread != null) {
19130                        try {
19131                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19132                                    "Trimming memory of ui hidden " + app.processName
19133                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19134                            app.thread.scheduleTrimMemory(
19135                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19136                        } catch (RemoteException e) {
19137                        }
19138                    }
19139                    app.pendingUiClean = false;
19140                }
19141                app.trimMemoryLevel = 0;
19142            }
19143        }
19144
19145        if (mAlwaysFinishActivities) {
19146            // Need to do this on its own message because the stack may not
19147            // be in a consistent state at this point.
19148            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19149        }
19150
19151        if (allChanged) {
19152            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19153        }
19154
19155        // Update from any uid changes.
19156        for (int i=mActiveUids.size()-1; i>=0; i--) {
19157            final UidRecord uidRec = mActiveUids.valueAt(i);
19158            if (uidRec.setProcState != uidRec.curProcState) {
19159                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19160                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19161                        + " to " + uidRec.curProcState);
19162                uidRec.setProcState = uidRec.curProcState;
19163                enqueueUidChangeLocked(uidRec, false);
19164            }
19165        }
19166
19167        if (mProcessStats.shouldWriteNowLocked(now)) {
19168            mHandler.post(new Runnable() {
19169                @Override public void run() {
19170                    synchronized (ActivityManagerService.this) {
19171                        mProcessStats.writeStateAsyncLocked();
19172                    }
19173                }
19174            });
19175        }
19176
19177        if (DEBUG_OOM_ADJ) {
19178            final long duration = SystemClock.uptimeMillis() - now;
19179            if (false) {
19180                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19181                        new RuntimeException("here").fillInStackTrace());
19182            } else {
19183                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19184            }
19185        }
19186    }
19187
19188    final void trimApplications() {
19189        synchronized (this) {
19190            int i;
19191
19192            // First remove any unused application processes whose package
19193            // has been removed.
19194            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19195                final ProcessRecord app = mRemovedProcesses.get(i);
19196                if (app.activities.size() == 0
19197                        && app.curReceiver == null && app.services.size() == 0) {
19198                    Slog.i(
19199                        TAG, "Exiting empty application process "
19200                        + app.processName + " ("
19201                        + (app.thread != null ? app.thread.asBinder() : null)
19202                        + ")\n");
19203                    if (app.pid > 0 && app.pid != MY_PID) {
19204                        app.kill("empty", false);
19205                    } else {
19206                        try {
19207                            app.thread.scheduleExit();
19208                        } catch (Exception e) {
19209                            // Ignore exceptions.
19210                        }
19211                    }
19212                    cleanUpApplicationRecordLocked(app, false, true, -1);
19213                    mRemovedProcesses.remove(i);
19214
19215                    if (app.persistent) {
19216                        addAppLocked(app.info, false, null /* ABI override */);
19217                    }
19218                }
19219            }
19220
19221            // Now update the oom adj for all processes.
19222            updateOomAdjLocked();
19223        }
19224    }
19225
19226    /** This method sends the specified signal to each of the persistent apps */
19227    public void signalPersistentProcesses(int sig) throws RemoteException {
19228        if (sig != Process.SIGNAL_USR1) {
19229            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19230        }
19231
19232        synchronized (this) {
19233            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19234                    != PackageManager.PERMISSION_GRANTED) {
19235                throw new SecurityException("Requires permission "
19236                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19237            }
19238
19239            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19240                ProcessRecord r = mLruProcesses.get(i);
19241                if (r.thread != null && r.persistent) {
19242                    Process.sendSignal(r.pid, sig);
19243                }
19244            }
19245        }
19246    }
19247
19248    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19249        if (proc == null || proc == mProfileProc) {
19250            proc = mProfileProc;
19251            profileType = mProfileType;
19252            clearProfilerLocked();
19253        }
19254        if (proc == null) {
19255            return;
19256        }
19257        try {
19258            proc.thread.profilerControl(false, null, profileType);
19259        } catch (RemoteException e) {
19260            throw new IllegalStateException("Process disappeared");
19261        }
19262    }
19263
19264    private void clearProfilerLocked() {
19265        if (mProfileFd != null) {
19266            try {
19267                mProfileFd.close();
19268            } catch (IOException e) {
19269            }
19270        }
19271        mProfileApp = null;
19272        mProfileProc = null;
19273        mProfileFile = null;
19274        mProfileType = 0;
19275        mAutoStopProfiler = false;
19276        mSamplingInterval = 0;
19277    }
19278
19279    public boolean profileControl(String process, int userId, boolean start,
19280            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19281
19282        try {
19283            synchronized (this) {
19284                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19285                // its own permission.
19286                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19287                        != PackageManager.PERMISSION_GRANTED) {
19288                    throw new SecurityException("Requires permission "
19289                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19290                }
19291
19292                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19293                    throw new IllegalArgumentException("null profile info or fd");
19294                }
19295
19296                ProcessRecord proc = null;
19297                if (process != null) {
19298                    proc = findProcessLocked(process, userId, "profileControl");
19299                }
19300
19301                if (start && (proc == null || proc.thread == null)) {
19302                    throw new IllegalArgumentException("Unknown process: " + process);
19303                }
19304
19305                if (start) {
19306                    stopProfilerLocked(null, 0);
19307                    setProfileApp(proc.info, proc.processName, profilerInfo);
19308                    mProfileProc = proc;
19309                    mProfileType = profileType;
19310                    ParcelFileDescriptor fd = profilerInfo.profileFd;
19311                    try {
19312                        fd = fd.dup();
19313                    } catch (IOException e) {
19314                        fd = null;
19315                    }
19316                    profilerInfo.profileFd = fd;
19317                    proc.thread.profilerControl(start, profilerInfo, profileType);
19318                    fd = null;
19319                    mProfileFd = null;
19320                } else {
19321                    stopProfilerLocked(proc, profileType);
19322                    if (profilerInfo != null && profilerInfo.profileFd != null) {
19323                        try {
19324                            profilerInfo.profileFd.close();
19325                        } catch (IOException e) {
19326                        }
19327                    }
19328                }
19329
19330                return true;
19331            }
19332        } catch (RemoteException e) {
19333            throw new IllegalStateException("Process disappeared");
19334        } finally {
19335            if (profilerInfo != null && profilerInfo.profileFd != null) {
19336                try {
19337                    profilerInfo.profileFd.close();
19338                } catch (IOException e) {
19339                }
19340            }
19341        }
19342    }
19343
19344    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19345        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19346                userId, true, ALLOW_FULL_ONLY, callName, null);
19347        ProcessRecord proc = null;
19348        try {
19349            int pid = Integer.parseInt(process);
19350            synchronized (mPidsSelfLocked) {
19351                proc = mPidsSelfLocked.get(pid);
19352            }
19353        } catch (NumberFormatException e) {
19354        }
19355
19356        if (proc == null) {
19357            ArrayMap<String, SparseArray<ProcessRecord>> all
19358                    = mProcessNames.getMap();
19359            SparseArray<ProcessRecord> procs = all.get(process);
19360            if (procs != null && procs.size() > 0) {
19361                proc = procs.valueAt(0);
19362                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19363                    for (int i=1; i<procs.size(); i++) {
19364                        ProcessRecord thisProc = procs.valueAt(i);
19365                        if (thisProc.userId == userId) {
19366                            proc = thisProc;
19367                            break;
19368                        }
19369                    }
19370                }
19371            }
19372        }
19373
19374        return proc;
19375    }
19376
19377    public boolean dumpHeap(String process, int userId, boolean managed,
19378            String path, ParcelFileDescriptor fd) throws RemoteException {
19379
19380        try {
19381            synchronized (this) {
19382                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19383                // its own permission (same as profileControl).
19384                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19385                        != PackageManager.PERMISSION_GRANTED) {
19386                    throw new SecurityException("Requires permission "
19387                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19388                }
19389
19390                if (fd == null) {
19391                    throw new IllegalArgumentException("null fd");
19392                }
19393
19394                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19395                if (proc == null || proc.thread == null) {
19396                    throw new IllegalArgumentException("Unknown process: " + process);
19397                }
19398
19399                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19400                if (!isDebuggable) {
19401                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19402                        throw new SecurityException("Process not debuggable: " + proc);
19403                    }
19404                }
19405
19406                proc.thread.dumpHeap(managed, path, fd);
19407                fd = null;
19408                return true;
19409            }
19410        } catch (RemoteException e) {
19411            throw new IllegalStateException("Process disappeared");
19412        } finally {
19413            if (fd != null) {
19414                try {
19415                    fd.close();
19416                } catch (IOException e) {
19417                }
19418            }
19419        }
19420    }
19421
19422    @Override
19423    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19424            String reportPackage) {
19425        if (processName != null) {
19426            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19427                    "setDumpHeapDebugLimit()");
19428        } else {
19429            synchronized (mPidsSelfLocked) {
19430                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19431                if (proc == null) {
19432                    throw new SecurityException("No process found for calling pid "
19433                            + Binder.getCallingPid());
19434                }
19435                if (!Build.IS_DEBUGGABLE
19436                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19437                    throw new SecurityException("Not running a debuggable build");
19438                }
19439                processName = proc.processName;
19440                uid = proc.uid;
19441                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19442                    throw new SecurityException("Package " + reportPackage + " is not running in "
19443                            + proc);
19444                }
19445            }
19446        }
19447        synchronized (this) {
19448            if (maxMemSize > 0) {
19449                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19450            } else {
19451                if (uid != 0) {
19452                    mMemWatchProcesses.remove(processName, uid);
19453                } else {
19454                    mMemWatchProcesses.getMap().remove(processName);
19455                }
19456            }
19457        }
19458    }
19459
19460    @Override
19461    public void dumpHeapFinished(String path) {
19462        synchronized (this) {
19463            if (Binder.getCallingPid() != mMemWatchDumpPid) {
19464                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19465                        + " does not match last pid " + mMemWatchDumpPid);
19466                return;
19467            }
19468            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19469                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19470                        + " does not match last path " + mMemWatchDumpFile);
19471                return;
19472            }
19473            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19474            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19475        }
19476    }
19477
19478    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19479    public void monitor() {
19480        synchronized (this) { }
19481    }
19482
19483    void onCoreSettingsChange(Bundle settings) {
19484        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19485            ProcessRecord processRecord = mLruProcesses.get(i);
19486            try {
19487                if (processRecord.thread != null) {
19488                    processRecord.thread.setCoreSettings(settings);
19489                }
19490            } catch (RemoteException re) {
19491                /* ignore */
19492            }
19493        }
19494    }
19495
19496    // Multi-user methods
19497
19498    /**
19499     * Start user, if its not already running, but don't bring it to foreground.
19500     */
19501    @Override
19502    public boolean startUserInBackground(final int userId) {
19503        return startUser(userId, /* foreground */ false);
19504    }
19505
19506    /**
19507     * Start user, if its not already running, and bring it to foreground.
19508     */
19509    boolean startUserInForeground(final int userId, Dialog dlg) {
19510        boolean result = startUser(userId, /* foreground */ true);
19511        dlg.dismiss();
19512        return result;
19513    }
19514
19515    /**
19516     * Refreshes the list of users related to the current user when either a
19517     * user switch happens or when a new related user is started in the
19518     * background.
19519     */
19520    private void updateCurrentProfileIdsLocked() {
19521        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19522                mCurrentUserId, false /* enabledOnly */);
19523        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19524        for (int i = 0; i < currentProfileIds.length; i++) {
19525            currentProfileIds[i] = profiles.get(i).id;
19526        }
19527        mCurrentProfileIds = currentProfileIds;
19528
19529        synchronized (mUserProfileGroupIdsSelfLocked) {
19530            mUserProfileGroupIdsSelfLocked.clear();
19531            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19532            for (int i = 0; i < users.size(); i++) {
19533                UserInfo user = users.get(i);
19534                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19535                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19536                }
19537            }
19538        }
19539    }
19540
19541    private Set<Integer> getProfileIdsLocked(int userId) {
19542        Set<Integer> userIds = new HashSet<Integer>();
19543        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19544                userId, false /* enabledOnly */);
19545        for (UserInfo user : profiles) {
19546            userIds.add(Integer.valueOf(user.id));
19547        }
19548        return userIds;
19549    }
19550
19551    @Override
19552    public boolean switchUser(final int userId) {
19553        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19554        String userName;
19555        synchronized (this) {
19556            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19557            if (userInfo == null) {
19558                Slog.w(TAG, "No user info for user #" + userId);
19559                return false;
19560            }
19561            if (userInfo.isManagedProfile()) {
19562                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19563                return false;
19564            }
19565            userName = userInfo.name;
19566            mTargetUserId = userId;
19567        }
19568        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19569        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19570        return true;
19571    }
19572
19573    private void showUserSwitchDialog(int userId, String userName) {
19574        // The dialog will show and then initiate the user switch by calling startUserInForeground
19575        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19576                true /* above system */);
19577        d.show();
19578    }
19579
19580    private boolean startUser(final int userId, final boolean foreground) {
19581        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19582                != PackageManager.PERMISSION_GRANTED) {
19583            String msg = "Permission Denial: switchUser() from pid="
19584                    + Binder.getCallingPid()
19585                    + ", uid=" + Binder.getCallingUid()
19586                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19587            Slog.w(TAG, msg);
19588            throw new SecurityException(msg);
19589        }
19590
19591        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19592
19593        final long ident = Binder.clearCallingIdentity();
19594        try {
19595            synchronized (this) {
19596                final int oldUserId = mCurrentUserId;
19597                if (oldUserId == userId) {
19598                    return true;
19599                }
19600
19601                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19602                        "startUser", false);
19603
19604                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19605                if (userInfo == null) {
19606                    Slog.w(TAG, "No user info for user #" + userId);
19607                    return false;
19608                }
19609                if (foreground && userInfo.isManagedProfile()) {
19610                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19611                    return false;
19612                }
19613
19614                if (foreground) {
19615                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19616                            R.anim.screen_user_enter);
19617                }
19618
19619                boolean needStart = false;
19620
19621                // If the user we are switching to is not currently started, then
19622                // we need to start it now.
19623                if (mStartedUsers.get(userId) == null) {
19624                    mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
19625                    updateStartedUserArrayLocked();
19626                    needStart = true;
19627                }
19628
19629                final Integer userIdInt = Integer.valueOf(userId);
19630                mUserLru.remove(userIdInt);
19631                mUserLru.add(userIdInt);
19632
19633                if (foreground) {
19634                    mCurrentUserId = userId;
19635                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19636                    updateCurrentProfileIdsLocked();
19637                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19638                    // Once the internal notion of the active user has switched, we lock the device
19639                    // with the option to show the user switcher on the keyguard.
19640                    mWindowManager.lockNow(null);
19641                } else {
19642                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19643                    updateCurrentProfileIdsLocked();
19644                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19645                    mUserLru.remove(currentUserIdInt);
19646                    mUserLru.add(currentUserIdInt);
19647                }
19648
19649                final UserState uss = mStartedUsers.get(userId);
19650
19651                // Make sure user is in the started state.  If it is currently
19652                // stopping, we need to knock that off.
19653                if (uss.mState == UserState.STATE_STOPPING) {
19654                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19655                    // so we can just fairly silently bring the user back from
19656                    // the almost-dead.
19657                    uss.mState = UserState.STATE_RUNNING;
19658                    updateStartedUserArrayLocked();
19659                    needStart = true;
19660                } else if (uss.mState == UserState.STATE_SHUTDOWN) {
19661                    // This means ACTION_SHUTDOWN has been sent, so we will
19662                    // need to treat this as a new boot of the user.
19663                    uss.mState = UserState.STATE_BOOTING;
19664                    updateStartedUserArrayLocked();
19665                    needStart = true;
19666                }
19667
19668                if (uss.mState == UserState.STATE_BOOTING) {
19669                    // Booting up a new user, need to tell system services about it.
19670                    // Note that this is on the same handler as scheduling of broadcasts,
19671                    // which is important because it needs to go first.
19672                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19673                }
19674
19675                if (foreground) {
19676                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19677                            oldUserId));
19678                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19679                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19680                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19681                            oldUserId, userId, uss));
19682                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19683                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19684                }
19685
19686                if (needStart) {
19687                    // Send USER_STARTED broadcast
19688                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19689                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19690                            | Intent.FLAG_RECEIVER_FOREGROUND);
19691                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19692                    broadcastIntentLocked(null, null, intent,
19693                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19694                            null, false, false, MY_PID, Process.SYSTEM_UID, userId);
19695                }
19696
19697                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19698                    if (userId != UserHandle.USER_OWNER) {
19699                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19700                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19701                        broadcastIntentLocked(null, null, intent, null,
19702                                new IIntentReceiver.Stub() {
19703                                    public void performReceive(Intent intent, int resultCode,
19704                                            String data, Bundle extras, boolean ordered,
19705                                            boolean sticky, int sendingUser) {
19706                                        onUserInitialized(uss, foreground, oldUserId, userId);
19707                                    }
19708                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19709                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19710                        uss.initializing = true;
19711                    } else {
19712                        getUserManagerLocked().makeInitialized(userInfo.id);
19713                    }
19714                }
19715
19716                if (foreground) {
19717                    if (!uss.initializing) {
19718                        moveUserToForeground(uss, oldUserId, userId);
19719                    }
19720                } else {
19721                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19722                }
19723
19724                if (needStart) {
19725                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19726                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19727                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19728                    broadcastIntentLocked(null, null, intent,
19729                            null, new IIntentReceiver.Stub() {
19730                                @Override
19731                                public void performReceive(Intent intent, int resultCode,
19732                                        String data, Bundle extras, boolean ordered, boolean sticky,
19733                                        int sendingUser) throws RemoteException {
19734                                }
19735                            }, 0, null, null,
19736                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19737                            null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19738                }
19739            }
19740        } finally {
19741            Binder.restoreCallingIdentity(ident);
19742        }
19743
19744        return true;
19745    }
19746
19747    void dispatchForegroundProfileChanged(int userId) {
19748        final int N = mUserSwitchObservers.beginBroadcast();
19749        for (int i = 0; i < N; i++) {
19750            try {
19751                mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19752            } catch (RemoteException e) {
19753                // Ignore
19754            }
19755        }
19756        mUserSwitchObservers.finishBroadcast();
19757    }
19758
19759    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19760        long ident = Binder.clearCallingIdentity();
19761        try {
19762            Intent intent;
19763            if (oldUserId >= 0) {
19764                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19765                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19766                int count = profiles.size();
19767                for (int i = 0; i < count; i++) {
19768                    int profileUserId = profiles.get(i).id;
19769                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19770                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19771                            | Intent.FLAG_RECEIVER_FOREGROUND);
19772                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19773                    broadcastIntentLocked(null, null, intent,
19774                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19775                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19776                }
19777            }
19778            if (newUserId >= 0) {
19779                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19780                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19781                int count = profiles.size();
19782                for (int i = 0; i < count; i++) {
19783                    int profileUserId = profiles.get(i).id;
19784                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19785                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19786                            | Intent.FLAG_RECEIVER_FOREGROUND);
19787                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19788                    broadcastIntentLocked(null, null, intent,
19789                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19790                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19791                }
19792                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19793                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19794                        | Intent.FLAG_RECEIVER_FOREGROUND);
19795                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19796                broadcastIntentLocked(null, null, intent,
19797                        null, null, 0, null, null,
19798                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19799                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19800            }
19801        } finally {
19802            Binder.restoreCallingIdentity(ident);
19803        }
19804    }
19805
19806    void dispatchUserSwitch(final UserState uss, final int oldUserId,
19807            final int newUserId) {
19808        final int N = mUserSwitchObservers.beginBroadcast();
19809        if (N > 0) {
19810            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19811                int mCount = 0;
19812                @Override
19813                public void sendResult(Bundle data) throws RemoteException {
19814                    synchronized (ActivityManagerService.this) {
19815                        if (mCurUserSwitchCallback == this) {
19816                            mCount++;
19817                            if (mCount == N) {
19818                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19819                            }
19820                        }
19821                    }
19822                }
19823            };
19824            synchronized (this) {
19825                uss.switching = true;
19826                mCurUserSwitchCallback = callback;
19827            }
19828            for (int i=0; i<N; i++) {
19829                try {
19830                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19831                            newUserId, callback);
19832                } catch (RemoteException e) {
19833                }
19834            }
19835        } else {
19836            synchronized (this) {
19837                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19838            }
19839        }
19840        mUserSwitchObservers.finishBroadcast();
19841    }
19842
19843    void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
19844        synchronized (this) {
19845            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19846            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19847        }
19848    }
19849
19850    void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
19851        mCurUserSwitchCallback = null;
19852        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19853        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19854                oldUserId, newUserId, uss));
19855    }
19856
19857    void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
19858        synchronized (this) {
19859            if (foreground) {
19860                moveUserToForeground(uss, oldUserId, newUserId);
19861            }
19862        }
19863
19864        completeSwitchAndInitalize(uss, newUserId, true, false);
19865    }
19866
19867    void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
19868        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19869        if (homeInFront) {
19870            startHomeActivityLocked(newUserId, "moveUserToFroreground");
19871        } else {
19872            mStackSupervisor.resumeTopActivitiesLocked();
19873        }
19874        EventLogTags.writeAmSwitchUser(newUserId);
19875        getUserManagerLocked().onUserForeground(newUserId);
19876        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19877    }
19878
19879    void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
19880        completeSwitchAndInitalize(uss, newUserId, false, true);
19881    }
19882
19883    void completeSwitchAndInitalize(UserState uss, int newUserId,
19884            boolean clearInitializing, boolean clearSwitching) {
19885        boolean unfrozen = false;
19886        synchronized (this) {
19887            if (clearInitializing) {
19888                uss.initializing = false;
19889                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19890            }
19891            if (clearSwitching) {
19892                uss.switching = false;
19893            }
19894            if (!uss.switching && !uss.initializing) {
19895                mWindowManager.stopFreezingScreen();
19896                unfrozen = true;
19897            }
19898        }
19899        if (unfrozen) {
19900            final int N = mUserSwitchObservers.beginBroadcast();
19901            for (int i=0; i<N; i++) {
19902                try {
19903                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19904                } catch (RemoteException e) {
19905                }
19906            }
19907            mUserSwitchObservers.finishBroadcast();
19908        }
19909        stopGuestUserIfBackground();
19910    }
19911
19912    /**
19913     * Stops the guest user if it has gone to the background.
19914     */
19915    private void stopGuestUserIfBackground() {
19916        synchronized (this) {
19917            final int num = mUserLru.size();
19918            for (int i = 0; i < num; i++) {
19919                Integer oldUserId = mUserLru.get(i);
19920                UserState oldUss = mStartedUsers.get(oldUserId);
19921                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19922                        || oldUss.mState == UserState.STATE_STOPPING
19923                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
19924                    continue;
19925                }
19926                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19927                if (userInfo.isGuest()) {
19928                    // This is a user to be stopped.
19929                    stopUserLocked(oldUserId, null);
19930                    break;
19931                }
19932            }
19933        }
19934    }
19935
19936    void scheduleStartProfilesLocked() {
19937        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19938            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19939                    DateUtils.SECOND_IN_MILLIS);
19940        }
19941    }
19942
19943    void startProfilesLocked() {
19944        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19945        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19946                mCurrentUserId, false /* enabledOnly */);
19947        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19948        for (UserInfo user : profiles) {
19949            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19950                    && user.id != mCurrentUserId) {
19951                toStart.add(user);
19952            }
19953        }
19954        final int n = toStart.size();
19955        int i = 0;
19956        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19957            startUserInBackground(toStart.get(i).id);
19958        }
19959        if (i < n) {
19960            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19961        }
19962    }
19963
19964    void finishUserBoot(UserState uss) {
19965        synchronized (this) {
19966            if (uss.mState == UserState.STATE_BOOTING
19967                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19968                uss.mState = UserState.STATE_RUNNING;
19969                final int userId = uss.mHandle.getIdentifier();
19970                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19971                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19972                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19973                broadcastIntentLocked(null, null, intent,
19974                        null, null, 0, null, null,
19975                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19976                        null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19977            }
19978        }
19979    }
19980
19981    void finishUserSwitch(UserState uss) {
19982        synchronized (this) {
19983            finishUserBoot(uss);
19984
19985            startProfilesLocked();
19986
19987            int num = mUserLru.size();
19988            int i = 0;
19989            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19990                Integer oldUserId = mUserLru.get(i);
19991                UserState oldUss = mStartedUsers.get(oldUserId);
19992                if (oldUss == null) {
19993                    // Shouldn't happen, but be sane if it does.
19994                    mUserLru.remove(i);
19995                    num--;
19996                    continue;
19997                }
19998                if (oldUss.mState == UserState.STATE_STOPPING
19999                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
20000                    // This user is already stopping, doesn't count.
20001                    num--;
20002                    i++;
20003                    continue;
20004                }
20005                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20006                    // Owner and current can't be stopped, but count as running.
20007                    i++;
20008                    continue;
20009                }
20010                // This is a user to be stopped.
20011                stopUserLocked(oldUserId, null);
20012                num--;
20013                i++;
20014            }
20015        }
20016    }
20017
20018    @Override
20019    public int stopUser(final int userId, final IStopUserCallback callback) {
20020        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20021                != PackageManager.PERMISSION_GRANTED) {
20022            String msg = "Permission Denial: switchUser() from pid="
20023                    + Binder.getCallingPid()
20024                    + ", uid=" + Binder.getCallingUid()
20025                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20026            Slog.w(TAG, msg);
20027            throw new SecurityException(msg);
20028        }
20029        if (userId < 0 || userId == UserHandle.USER_OWNER) {
20030            throw new IllegalArgumentException("Can't stop primary user " + userId);
20031        }
20032        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20033        synchronized (this) {
20034            return stopUserLocked(userId, callback);
20035        }
20036    }
20037
20038    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20039        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20040        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20041            return ActivityManager.USER_OP_IS_CURRENT;
20042        }
20043
20044        final UserState uss = mStartedUsers.get(userId);
20045        if (uss == null) {
20046            // User is not started, nothing to do...  but we do need to
20047            // callback if requested.
20048            if (callback != null) {
20049                mHandler.post(new Runnable() {
20050                    @Override
20051                    public void run() {
20052                        try {
20053                            callback.userStopped(userId);
20054                        } catch (RemoteException e) {
20055                        }
20056                    }
20057                });
20058            }
20059            return ActivityManager.USER_OP_SUCCESS;
20060        }
20061
20062        if (callback != null) {
20063            uss.mStopCallbacks.add(callback);
20064        }
20065
20066        if (uss.mState != UserState.STATE_STOPPING
20067                && uss.mState != UserState.STATE_SHUTDOWN) {
20068            uss.mState = UserState.STATE_STOPPING;
20069            updateStartedUserArrayLocked();
20070
20071            long ident = Binder.clearCallingIdentity();
20072            try {
20073                // We are going to broadcast ACTION_USER_STOPPING and then
20074                // once that is done send a final ACTION_SHUTDOWN and then
20075                // stop the user.
20076                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20077                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20078                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20079                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20080                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20081                // This is the result receiver for the final shutdown broadcast.
20082                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20083                    @Override
20084                    public void performReceive(Intent intent, int resultCode, String data,
20085                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20086                        finishUserStop(uss);
20087                    }
20088                };
20089                // This is the result receiver for the initial stopping broadcast.
20090                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20091                    @Override
20092                    public void performReceive(Intent intent, int resultCode, String data,
20093                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20094                        // On to the next.
20095                        synchronized (ActivityManagerService.this) {
20096                            if (uss.mState != UserState.STATE_STOPPING) {
20097                                // Whoops, we are being started back up.  Abort, abort!
20098                                return;
20099                            }
20100                            uss.mState = UserState.STATE_SHUTDOWN;
20101                        }
20102                        mBatteryStatsService.noteEvent(
20103                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20104                                Integer.toString(userId), userId);
20105                        mSystemServiceManager.stopUser(userId);
20106                        broadcastIntentLocked(null, null, shutdownIntent,
20107                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20108                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20109                    }
20110                };
20111                // Kick things off.
20112                broadcastIntentLocked(null, null, stoppingIntent,
20113                        null, stoppingReceiver, 0, null, null,
20114                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
20115                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20116            } finally {
20117                Binder.restoreCallingIdentity(ident);
20118            }
20119        }
20120
20121        return ActivityManager.USER_OP_SUCCESS;
20122    }
20123
20124    void finishUserStop(UserState uss) {
20125        final int userId = uss.mHandle.getIdentifier();
20126        boolean stopped;
20127        ArrayList<IStopUserCallback> callbacks;
20128        synchronized (this) {
20129            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20130            if (mStartedUsers.get(userId) != uss) {
20131                stopped = false;
20132            } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20133                stopped = false;
20134            } else {
20135                stopped = true;
20136                // User can no longer run.
20137                mStartedUsers.remove(userId);
20138                mUserLru.remove(Integer.valueOf(userId));
20139                updateStartedUserArrayLocked();
20140
20141                // Clean up all state and processes associated with the user.
20142                // Kill all the processes for the user.
20143                forceStopUserLocked(userId, "finish user");
20144            }
20145
20146            // Explicitly remove the old information in mRecentTasks.
20147            mRecentTasks.removeTasksForUserLocked(userId);
20148        }
20149
20150        for (int i=0; i<callbacks.size(); i++) {
20151            try {
20152                if (stopped) callbacks.get(i).userStopped(userId);
20153                else callbacks.get(i).userStopAborted(userId);
20154            } catch (RemoteException e) {
20155            }
20156        }
20157
20158        if (stopped) {
20159            mSystemServiceManager.cleanupUser(userId);
20160            synchronized (this) {
20161                mStackSupervisor.removeUserLocked(userId);
20162            }
20163        }
20164    }
20165
20166    @Override
20167    public UserInfo getCurrentUser() {
20168        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20169                != PackageManager.PERMISSION_GRANTED) && (
20170                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20171                != PackageManager.PERMISSION_GRANTED)) {
20172            String msg = "Permission Denial: getCurrentUser() from pid="
20173                    + Binder.getCallingPid()
20174                    + ", uid=" + Binder.getCallingUid()
20175                    + " requires " + INTERACT_ACROSS_USERS;
20176            Slog.w(TAG, msg);
20177            throw new SecurityException(msg);
20178        }
20179        synchronized (this) {
20180            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20181            return getUserManagerLocked().getUserInfo(userId);
20182        }
20183    }
20184
20185    int getCurrentUserIdLocked() {
20186        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20187    }
20188
20189    @Override
20190    public boolean isUserRunning(int userId, boolean orStopped) {
20191        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20192                != PackageManager.PERMISSION_GRANTED) {
20193            String msg = "Permission Denial: isUserRunning() from pid="
20194                    + Binder.getCallingPid()
20195                    + ", uid=" + Binder.getCallingUid()
20196                    + " requires " + INTERACT_ACROSS_USERS;
20197            Slog.w(TAG, msg);
20198            throw new SecurityException(msg);
20199        }
20200        synchronized (this) {
20201            return isUserRunningLocked(userId, orStopped);
20202        }
20203    }
20204
20205    boolean isUserRunningLocked(int userId, boolean orStopped) {
20206        UserState state = mStartedUsers.get(userId);
20207        if (state == null) {
20208            return false;
20209        }
20210        if (orStopped) {
20211            return true;
20212        }
20213        return state.mState != UserState.STATE_STOPPING
20214                && state.mState != UserState.STATE_SHUTDOWN;
20215    }
20216
20217    @Override
20218    public int[] getRunningUserIds() {
20219        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20220                != PackageManager.PERMISSION_GRANTED) {
20221            String msg = "Permission Denial: isUserRunning() from pid="
20222                    + Binder.getCallingPid()
20223                    + ", uid=" + Binder.getCallingUid()
20224                    + " requires " + INTERACT_ACROSS_USERS;
20225            Slog.w(TAG, msg);
20226            throw new SecurityException(msg);
20227        }
20228        synchronized (this) {
20229            return mStartedUserArray;
20230        }
20231    }
20232
20233    private void updateStartedUserArrayLocked() {
20234        int num = 0;
20235        for (int i=0; i<mStartedUsers.size();  i++) {
20236            UserState uss = mStartedUsers.valueAt(i);
20237            // This list does not include stopping users.
20238            if (uss.mState != UserState.STATE_STOPPING
20239                    && uss.mState != UserState.STATE_SHUTDOWN) {
20240                num++;
20241            }
20242        }
20243        mStartedUserArray = new int[num];
20244        num = 0;
20245        for (int i=0; i<mStartedUsers.size();  i++) {
20246            UserState uss = mStartedUsers.valueAt(i);
20247            if (uss.mState != UserState.STATE_STOPPING
20248                    && uss.mState != UserState.STATE_SHUTDOWN) {
20249                mStartedUserArray[num] = mStartedUsers.keyAt(i);
20250                num++;
20251            }
20252        }
20253    }
20254
20255    @Override
20256    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20257        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20258                != PackageManager.PERMISSION_GRANTED) {
20259            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20260                    + Binder.getCallingPid()
20261                    + ", uid=" + Binder.getCallingUid()
20262                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20263            Slog.w(TAG, msg);
20264            throw new SecurityException(msg);
20265        }
20266
20267        mUserSwitchObservers.register(observer);
20268    }
20269
20270    @Override
20271    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20272        mUserSwitchObservers.unregister(observer);
20273    }
20274
20275    int[] getUsersLocked() {
20276        UserManagerService ums = getUserManagerLocked();
20277        return ums != null ? ums.getUserIds() : new int[] { 0 };
20278    }
20279
20280    UserManagerService getUserManagerLocked() {
20281        if (mUserManager == null) {
20282            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20283            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20284        }
20285        return mUserManager;
20286    }
20287
20288    private int applyUserId(int uid, int userId) {
20289        return UserHandle.getUid(userId, uid);
20290    }
20291
20292    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20293        if (info == null) return null;
20294        ApplicationInfo newInfo = new ApplicationInfo(info);
20295        newInfo.uid = applyUserId(info.uid, userId);
20296        newInfo.dataDir = PackageManager.getDataDirForUser(info.volumeUuid, info.packageName,
20297                userId).getAbsolutePath();
20298        return newInfo;
20299    }
20300
20301    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20302        if (aInfo == null
20303                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20304            return aInfo;
20305        }
20306
20307        ActivityInfo info = new ActivityInfo(aInfo);
20308        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20309        return info;
20310    }
20311
20312    private final class LocalService extends ActivityManagerInternal {
20313        @Override
20314        public void onWakefulnessChanged(int wakefulness) {
20315            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20316        }
20317
20318        @Override
20319        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20320                String processName, String abiOverride, int uid, Runnable crashHandler) {
20321            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20322                    processName, abiOverride, uid, crashHandler);
20323        }
20324
20325        @Override
20326        public SleepToken acquireSleepToken(String tag) {
20327            Preconditions.checkNotNull(tag);
20328
20329            synchronized (ActivityManagerService.this) {
20330                SleepTokenImpl token = new SleepTokenImpl(tag);
20331                mSleepTokens.add(token);
20332                updateSleepIfNeededLocked();
20333                return token;
20334            }
20335        }
20336
20337        @Override
20338        public ComponentName getHomeActivityForUser(int userId) {
20339            synchronized (ActivityManagerService.this) {
20340                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20341                return homeActivity == null ? null : homeActivity.realActivity;
20342            }
20343        }
20344    }
20345
20346    private final class SleepTokenImpl extends SleepToken {
20347        private final String mTag;
20348        private final long mAcquireTime;
20349
20350        public SleepTokenImpl(String tag) {
20351            mTag = tag;
20352            mAcquireTime = SystemClock.uptimeMillis();
20353        }
20354
20355        @Override
20356        public void release() {
20357            synchronized (ActivityManagerService.this) {
20358                if (mSleepTokens.remove(this)) {
20359                    updateSleepIfNeededLocked();
20360                }
20361            }
20362        }
20363
20364        @Override
20365        public String toString() {
20366            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20367        }
20368    }
20369
20370    /**
20371     * An implementation of IAppTask, that allows an app to manage its own tasks via
20372     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20373     * only the process that calls getAppTasks() can call the AppTask methods.
20374     */
20375    class AppTaskImpl extends IAppTask.Stub {
20376        private int mTaskId;
20377        private int mCallingUid;
20378
20379        public AppTaskImpl(int taskId, int callingUid) {
20380            mTaskId = taskId;
20381            mCallingUid = callingUid;
20382        }
20383
20384        private void checkCaller() {
20385            if (mCallingUid != Binder.getCallingUid()) {
20386                throw new SecurityException("Caller " + mCallingUid
20387                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20388            }
20389        }
20390
20391        @Override
20392        public void finishAndRemoveTask() {
20393            checkCaller();
20394
20395            synchronized (ActivityManagerService.this) {
20396                long origId = Binder.clearCallingIdentity();
20397                try {
20398                    if (!removeTaskByIdLocked(mTaskId, false)) {
20399                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20400                    }
20401                } finally {
20402                    Binder.restoreCallingIdentity(origId);
20403                }
20404            }
20405        }
20406
20407        @Override
20408        public ActivityManager.RecentTaskInfo getTaskInfo() {
20409            checkCaller();
20410
20411            synchronized (ActivityManagerService.this) {
20412                long origId = Binder.clearCallingIdentity();
20413                try {
20414                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20415                    if (tr == null) {
20416                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20417                    }
20418                    return createRecentTaskInfoFromTaskRecord(tr);
20419                } finally {
20420                    Binder.restoreCallingIdentity(origId);
20421                }
20422            }
20423        }
20424
20425        @Override
20426        public void moveToFront() {
20427            checkCaller();
20428            // Will bring task to front if it already has a root activity.
20429            startActivityFromRecentsInner(mTaskId, null);
20430        }
20431
20432        @Override
20433        public int startActivity(IBinder whoThread, String callingPackage,
20434                Intent intent, String resolvedType, Bundle options) {
20435            checkCaller();
20436
20437            int callingUser = UserHandle.getCallingUserId();
20438            TaskRecord tr;
20439            IApplicationThread appThread;
20440            synchronized (ActivityManagerService.this) {
20441                tr = mRecentTasks.taskForIdLocked(mTaskId);
20442                if (tr == null) {
20443                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20444                }
20445                appThread = ApplicationThreadNative.asInterface(whoThread);
20446                if (appThread == null) {
20447                    throw new IllegalArgumentException("Bad app thread " + appThread);
20448                }
20449            }
20450            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20451                    resolvedType, null, null, null, null, 0, 0, null, null,
20452                    null, options, callingUser, null, tr);
20453        }
20454
20455        @Override
20456        public void setExcludeFromRecents(boolean exclude) {
20457            checkCaller();
20458
20459            synchronized (ActivityManagerService.this) {
20460                long origId = Binder.clearCallingIdentity();
20461                try {
20462                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20463                    if (tr == null) {
20464                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20465                    }
20466                    Intent intent = tr.getBaseIntent();
20467                    if (exclude) {
20468                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20469                    } else {
20470                        intent.setFlags(intent.getFlags()
20471                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20472                    }
20473                } finally {
20474                    Binder.restoreCallingIdentity(origId);
20475                }
20476            }
20477        }
20478    }
20479}
20480