ActivityManagerService.java revision d80c263e2a45f0a2b65fd9762aa8deea49c8ca72
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 org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33import static com.android.server.am.ActivityManagerDebugConfig.*;
34import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
35
36import android.Manifest;
37import android.app.AppOpsManager;
38import android.app.ApplicationThreadNative;
39import android.app.IActivityContainer;
40import android.app.IActivityContainerCallback;
41import android.app.IAppTask;
42import android.app.ITaskStackListener;
43import android.app.ProfilerInfo;
44import android.app.admin.DevicePolicyManager;
45import android.app.usage.UsageEvents;
46import android.app.usage.UsageStatsManagerInternal;
47import android.appwidget.AppWidgetManager;
48import android.content.res.Resources;
49import android.graphics.Bitmap;
50import android.graphics.Point;
51import android.graphics.Rect;
52import android.os.BatteryStats;
53import android.os.PersistableBundle;
54import android.os.storage.IMountService;
55import android.os.storage.StorageManager;
56import android.service.voice.IVoiceInteractionSession;
57import android.util.ArrayMap;
58import android.util.ArraySet;
59import android.util.DebugUtils;
60import android.util.SparseIntArray;
61
62import android.view.Display;
63import com.android.internal.R;
64import com.android.internal.annotations.GuardedBy;
65import com.android.internal.app.DumpHeapActivity;
66import com.android.internal.app.IAppOpsService;
67import com.android.internal.app.IVoiceInteractor;
68import com.android.internal.app.ProcessMap;
69import com.android.internal.app.ProcessStats;
70import com.android.internal.os.BackgroundThread;
71import com.android.internal.os.BatteryStatsImpl;
72import com.android.internal.os.IResultReceiver;
73import com.android.internal.os.ProcessCpuTracker;
74import com.android.internal.os.TransferPipe;
75import com.android.internal.os.Zygote;
76import com.android.internal.util.FastPrintWriter;
77import com.android.internal.util.FastXmlSerializer;
78import com.android.internal.util.MemInfoReader;
79import com.android.internal.util.Preconditions;
80import com.android.server.AppOpsService;
81import com.android.server.AttributeCache;
82import com.android.server.IntentResolver;
83import com.android.server.LocalServices;
84import com.android.server.ServiceThread;
85import com.android.server.SystemService;
86import com.android.server.SystemServiceManager;
87import com.android.server.Watchdog;
88import com.android.server.am.ActivityStack.ActivityState;
89import com.android.server.firewall.IntentFirewall;
90import com.android.server.pm.Installer;
91import com.android.server.pm.UserManagerService;
92import com.android.server.statusbar.StatusBarManagerInternal;
93import com.android.server.wm.AppTransition;
94import com.android.server.wm.WindowManagerService;
95
96import com.google.android.collect.Lists;
97import com.google.android.collect.Maps;
98
99import libcore.io.IoUtils;
100
101import org.xmlpull.v1.XmlPullParser;
102import org.xmlpull.v1.XmlPullParserException;
103import org.xmlpull.v1.XmlSerializer;
104
105import android.app.Activity;
106import android.app.ActivityManager;
107import android.app.ActivityManager.RunningTaskInfo;
108import android.app.ActivityManager.StackInfo;
109import android.app.ActivityManagerInternal;
110import android.app.ActivityManagerNative;
111import android.app.ActivityOptions;
112import android.app.ActivityThread;
113import android.app.AlertDialog;
114import android.app.AppGlobals;
115import android.app.ApplicationErrorReport;
116import android.app.Dialog;
117import android.app.IActivityController;
118import android.app.IApplicationThread;
119import android.app.IInstrumentationWatcher;
120import android.app.INotificationManager;
121import android.app.IProcessObserver;
122import android.app.IServiceConnection;
123import android.app.IStopUserCallback;
124import android.app.IUiAutomationConnection;
125import android.app.IUserSwitchObserver;
126import android.app.Instrumentation;
127import android.app.Notification;
128import android.app.NotificationManager;
129import android.app.PendingIntent;
130import android.app.backup.IBackupManager;
131import android.content.ActivityNotFoundException;
132import android.content.BroadcastReceiver;
133import android.content.ClipData;
134import android.content.ComponentCallbacks2;
135import android.content.ComponentName;
136import android.content.ContentProvider;
137import android.content.ContentResolver;
138import android.content.Context;
139import android.content.DialogInterface;
140import android.content.IContentProvider;
141import android.content.IIntentReceiver;
142import android.content.IIntentSender;
143import android.content.Intent;
144import android.content.IntentFilter;
145import android.content.IntentSender;
146import android.content.pm.ActivityInfo;
147import android.content.pm.ApplicationInfo;
148import android.content.pm.ConfigurationInfo;
149import android.content.pm.IPackageDataObserver;
150import android.content.pm.IPackageManager;
151import android.content.pm.InstrumentationInfo;
152import android.content.pm.PackageInfo;
153import android.content.pm.PackageManager;
154import android.content.pm.ParceledListSlice;
155import android.content.pm.UserInfo;
156import android.content.pm.PackageManager.NameNotFoundException;
157import android.content.pm.PathPermission;
158import android.content.pm.ProviderInfo;
159import android.content.pm.ResolveInfo;
160import android.content.pm.ServiceInfo;
161import android.content.res.CompatibilityInfo;
162import android.content.res.Configuration;
163import android.net.Proxy;
164import android.net.ProxyInfo;
165import android.net.Uri;
166import android.os.Binder;
167import android.os.Build;
168import android.os.Bundle;
169import android.os.Debug;
170import android.os.DropBoxManager;
171import android.os.Environment;
172import android.os.FactoryTest;
173import android.os.FileObserver;
174import android.os.FileUtils;
175import android.os.Handler;
176import android.os.IBinder;
177import android.os.IPermissionController;
178import android.os.IProcessInfoService;
179import android.os.IRemoteCallback;
180import android.os.IUserManager;
181import android.os.Looper;
182import android.os.Message;
183import android.os.Parcel;
184import android.os.ParcelFileDescriptor;
185import android.os.PowerManagerInternal;
186import android.os.Process;
187import android.os.RemoteCallbackList;
188import android.os.RemoteException;
189import android.os.SELinux;
190import android.os.ServiceManager;
191import android.os.StrictMode;
192import android.os.SystemClock;
193import android.os.SystemProperties;
194import android.os.UpdateLock;
195import android.os.UserHandle;
196import android.os.UserManager;
197import android.provider.Settings;
198import android.text.format.DateUtils;
199import android.text.format.Time;
200import android.util.AtomicFile;
201import android.util.EventLog;
202import android.util.Log;
203import android.util.Pair;
204import android.util.PrintWriterPrinter;
205import android.util.Slog;
206import android.util.SparseArray;
207import android.util.TimeUtils;
208import android.util.Xml;
209import android.view.Gravity;
210import android.view.LayoutInflater;
211import android.view.View;
212import android.view.WindowManager;
213
214import dalvik.system.VMRuntime;
215
216import java.io.BufferedInputStream;
217import java.io.BufferedOutputStream;
218import java.io.DataInputStream;
219import java.io.DataOutputStream;
220import java.io.File;
221import java.io.FileDescriptor;
222import java.io.FileInputStream;
223import java.io.FileNotFoundException;
224import java.io.FileOutputStream;
225import java.io.IOException;
226import java.io.InputStreamReader;
227import java.io.PrintWriter;
228import java.io.StringWriter;
229import java.lang.ref.WeakReference;
230import java.util.ArrayList;
231import java.util.Arrays;
232import java.util.Collections;
233import java.util.Comparator;
234import java.util.HashMap;
235import java.util.HashSet;
236import java.util.Iterator;
237import java.util.List;
238import java.util.Locale;
239import java.util.Map;
240import java.util.Set;
241import java.util.concurrent.atomic.AtomicBoolean;
242import java.util.concurrent.atomic.AtomicLong;
243
244public final class ActivityManagerService extends ActivityManagerNative
245        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
246
247    private static final String USER_DATA_DIR = "/data/user/";
248    // File that stores last updated system version and called preboot receivers
249    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
250
251    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
252    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
253    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
254    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
255    private static final String TAG_MU = TAG + POSTFIX_MU;
256
257    // TODO(ogunwale): Migrate all the constants below to use ActivityManagerDebugConfig class.
258    static final boolean DEBUG_CONFIGURATION = DEBUG_ALL || false;
259    static final boolean DEBUG_FOCUS = false;
260    static final boolean DEBUG_IMMERSIVE = DEBUG_ALL || false;
261    static final boolean DEBUG_MU = DEBUG_ALL || false;
262    static final boolean DEBUG_OOM_ADJ = DEBUG_ALL || false;
263    static final boolean DEBUG_LRU = DEBUG_ALL || false;
264    static final boolean DEBUG_PAUSE = DEBUG_ALL || false;
265    static final boolean DEBUG_POWER = DEBUG_ALL || false;
266    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
267    static final boolean DEBUG_PROCESS_OBSERVERS = DEBUG_ALL || false;
268    static final boolean DEBUG_PROCESSES = DEBUG_ALL || false;
269    static final boolean DEBUG_PROVIDER = DEBUG_ALL || false;
270    static final boolean DEBUG_RESULTS = DEBUG_ALL || false;
271    static final boolean DEBUG_SERVICE = DEBUG_ALL || false;
272    static final boolean DEBUG_SERVICE_EXECUTING = DEBUG_ALL || false;
273    static final boolean DEBUG_STACK = DEBUG_ALL || false;
274    static final boolean DEBUG_SWITCH = DEBUG_ALL || false;
275    static final boolean DEBUG_TASKS = DEBUG_ALL || false;
276    static final boolean DEBUG_THUMBNAILS = DEBUG_ALL || false;
277    static final boolean DEBUG_TRANSITION = DEBUG_ALL || false;
278    static final boolean DEBUG_URI_PERMISSION = DEBUG_ALL || false;
279    static final boolean DEBUG_USER_LEAVING = DEBUG_ALL || false;
280    static final boolean DEBUG_VISBILITY = DEBUG_ALL || false;
281    static final boolean DEBUG_PSS = DEBUG_ALL || false;
282    static final boolean DEBUG_LOCKSCREEN = DEBUG_ALL || false;
283    static final boolean DEBUG_RECENTS = DEBUG_ALL || false;
284    static final boolean VALIDATE_TOKENS = false;
285    static final boolean SHOW_ACTIVITY_START_TIME = true;
286
287    // Control over CPU and battery monitoring.
288    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
289    static final boolean MONITOR_CPU_USAGE = true;
290    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
291    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
292    static final boolean MONITOR_THREAD_CPU_USAGE = false;
293
294    // The flags that are set for all calls we make to the package manager.
295    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
296
297    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
298
299    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
300
301    // Amount of time after a call to stopAppSwitches() during which we will
302    // prevent further untrusted switches from happening.
303    static final long APP_SWITCH_DELAY_TIME = 5*1000;
304
305    // How long we wait for a launched process to attach to the activity manager
306    // before we decide it's never going to come up for real.
307    static final int PROC_START_TIMEOUT = 10*1000;
308
309    // How long we wait for a launched process to attach to the activity manager
310    // before we decide it's never going to come up for real, when the process was
311    // started with a wrapper for instrumentation (such as Valgrind) because it
312    // could take much longer than usual.
313    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
314
315    // How long to wait after going idle before forcing apps to GC.
316    static final int GC_TIMEOUT = 5*1000;
317
318    // The minimum amount of time between successive GC requests for a process.
319    static final int GC_MIN_INTERVAL = 60*1000;
320
321    // The minimum amount of time between successive PSS requests for a process.
322    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
323
324    // The minimum amount of time between successive PSS requests for a process
325    // when the request is due to the memory state being lowered.
326    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
327
328    // The rate at which we check for apps using excessive power -- 15 mins.
329    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
330
331    // The minimum sample duration we will allow before deciding we have
332    // enough data on wake locks to start killing things.
333    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
334
335    // The minimum sample duration we will allow before deciding we have
336    // enough data on CPU usage to start killing things.
337    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
338
339    // How long we allow a receiver to run before giving up on it.
340    static final int BROADCAST_FG_TIMEOUT = 10*1000;
341    static final int BROADCAST_BG_TIMEOUT = 60*1000;
342
343    // How long we wait until we timeout on key dispatching.
344    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
345
346    // How long we wait until we timeout on key dispatching during instrumentation.
347    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
348
349    // Amount of time we wait for observers to handle a user switch before
350    // giving up on them and unfreezing the screen.
351    static final int USER_SWITCH_TIMEOUT = 2*1000;
352
353    // Maximum number of users we allow to be running at a time.
354    static final int MAX_RUNNING_USERS = 3;
355
356    // How long to wait in getAssistContextExtras for the activity and foreground services
357    // to respond with the result.
358    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
359
360    // Maximum number of persisted Uri grants a package is allowed
361    static final int MAX_PERSISTED_URI_GRANTS = 128;
362
363    static final int MY_PID = Process.myPid();
364
365    static final String[] EMPTY_STRING_ARRAY = new String[0];
366
367    // How many bytes to write into the dropbox log before truncating
368    static final int DROPBOX_MAX_SIZE = 256 * 1024;
369
370    // Access modes for handleIncomingUser.
371    static final int ALLOW_NON_FULL = 0;
372    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
373    static final int ALLOW_FULL_ONLY = 2;
374
375    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
376
377    // Delay in notifying task stack change listeners (in millis)
378    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
379
380    /** All system services */
381    SystemServiceManager mSystemServiceManager;
382
383    private Installer mInstaller;
384
385    /** Run all ActivityStacks through this */
386    ActivityStackSupervisor mStackSupervisor;
387
388    /** Task stack change listeners. */
389    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
390            new RemoteCallbackList<ITaskStackListener>();
391
392    public IntentFirewall mIntentFirewall;
393
394    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
395    // default actuion automatically.  Important for devices without direct input
396    // devices.
397    private boolean mShowDialogs = true;
398
399    BroadcastQueue mFgBroadcastQueue;
400    BroadcastQueue mBgBroadcastQueue;
401    // Convenient for easy iteration over the queues. Foreground is first
402    // so that dispatch of foreground broadcasts gets precedence.
403    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
404
405    BroadcastQueue broadcastQueueForIntent(Intent intent) {
406        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
407        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
408                "Broadcast intent " + intent + " on "
409                + (isFg ? "foreground" : "background") + " queue");
410        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
411    }
412
413    /**
414     * Activity we have told the window manager to have key focus.
415     */
416    ActivityRecord mFocusedActivity = null;
417
418    /**
419     * List of intents that were used to start the most recent tasks.
420     */
421    private final RecentTasks mRecentTasks;
422
423    /**
424     * For addAppTask: cached of the last activity component that was added.
425     */
426    ComponentName mLastAddedTaskComponent;
427
428    /**
429     * For addAppTask: cached of the last activity uid that was added.
430     */
431    int mLastAddedTaskUid;
432
433    /**
434     * For addAppTask: cached of the last ActivityInfo that was added.
435     */
436    ActivityInfo mLastAddedTaskActivity;
437
438    public class PendingAssistExtras extends Binder implements Runnable {
439        public final ActivityRecord activity;
440        public final Bundle extras;
441        public final Intent intent;
442        public final String hint;
443        public final IResultReceiver receiver;
444        public final int userHandle;
445        public boolean haveResult = false;
446        public Bundle result = null;
447        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
448                String _hint, IResultReceiver _receiver, int _userHandle) {
449            activity = _activity;
450            extras = _extras;
451            intent = _intent;
452            hint = _hint;
453            receiver = _receiver;
454            userHandle = _userHandle;
455        }
456        @Override
457        public void run() {
458            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
459            synchronized (ActivityManagerService.this) {
460                synchronized (this) {
461                    haveResult = true;
462                    notifyAll();
463                }
464                pendingAssistExtrasTimedOutLocked(this);
465            }
466        }
467    }
468
469    final ArrayList<PendingAssistExtras> mPendingAssistExtras
470            = new ArrayList<PendingAssistExtras>();
471
472    /**
473     * Process management.
474     */
475    final ProcessList mProcessList = new ProcessList();
476
477    /**
478     * All of the applications we currently have running organized by name.
479     * The keys are strings of the application package name (as
480     * returned by the package manager), and the keys are ApplicationRecord
481     * objects.
482     */
483    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
484
485    /**
486     * Tracking long-term execution of processes to look for abuse and other
487     * bad app behavior.
488     */
489    final ProcessStatsService mProcessStats;
490
491    /**
492     * The currently running isolated processes.
493     */
494    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
495
496    /**
497     * Counter for assigning isolated process uids, to avoid frequently reusing the
498     * same ones.
499     */
500    int mNextIsolatedProcessUid = 0;
501
502    /**
503     * The currently running heavy-weight process, if any.
504     */
505    ProcessRecord mHeavyWeightProcess = null;
506
507    /**
508     * The last time that various processes have crashed.
509     */
510    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
511
512    /**
513     * Information about a process that is currently marked as bad.
514     */
515    static final class BadProcessInfo {
516        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
517            this.time = time;
518            this.shortMsg = shortMsg;
519            this.longMsg = longMsg;
520            this.stack = stack;
521        }
522
523        final long time;
524        final String shortMsg;
525        final String longMsg;
526        final String stack;
527    }
528
529    /**
530     * Set of applications that we consider to be bad, and will reject
531     * incoming broadcasts from (which the user has no control over).
532     * Processes are added to this set when they have crashed twice within
533     * a minimum amount of time; they are removed from it when they are
534     * later restarted (hopefully due to some user action).  The value is the
535     * time it was added to the list.
536     */
537    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
538
539    /**
540     * All of the processes we currently have running organized by pid.
541     * The keys are the pid running the application.
542     *
543     * <p>NOTE: This object is protected by its own lock, NOT the global
544     * activity manager lock!
545     */
546    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
547
548    /**
549     * All of the processes that have been forced to be foreground.  The key
550     * is the pid of the caller who requested it (we hold a death
551     * link on it).
552     */
553    abstract class ForegroundToken implements IBinder.DeathRecipient {
554        int pid;
555        IBinder token;
556    }
557    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
558
559    /**
560     * List of records for processes that someone had tried to start before the
561     * system was ready.  We don't start them at that point, but ensure they
562     * are started by the time booting is complete.
563     */
564    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
565
566    /**
567     * List of persistent applications that are in the process
568     * of being started.
569     */
570    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
571
572    /**
573     * Processes that are being forcibly torn down.
574     */
575    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
576
577    /**
578     * List of running applications, sorted by recent usage.
579     * The first entry in the list is the least recently used.
580     */
581    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
582
583    /**
584     * Where in mLruProcesses that the processes hosting activities start.
585     */
586    int mLruProcessActivityStart = 0;
587
588    /**
589     * Where in mLruProcesses that the processes hosting services start.
590     * This is after (lower index) than mLruProcessesActivityStart.
591     */
592    int mLruProcessServiceStart = 0;
593
594    /**
595     * List of processes that should gc as soon as things are idle.
596     */
597    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
598
599    /**
600     * Processes we want to collect PSS data from.
601     */
602    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
603
604    /**
605     * Last time we requested PSS data of all processes.
606     */
607    long mLastFullPssTime = SystemClock.uptimeMillis();
608
609    /**
610     * If set, the next time we collect PSS data we should do a full collection
611     * with data from native processes and the kernel.
612     */
613    boolean mFullPssPending = false;
614
615    /**
616     * This is the process holding what we currently consider to be
617     * the "home" activity.
618     */
619    ProcessRecord mHomeProcess;
620
621    /**
622     * This is the process holding the activity the user last visited that
623     * is in a different process from the one they are currently in.
624     */
625    ProcessRecord mPreviousProcess;
626
627    /**
628     * The time at which the previous process was last visible.
629     */
630    long mPreviousProcessVisibleTime;
631
632    /**
633     * Which uses have been started, so are allowed to run code.
634     */
635    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
636
637    /**
638     * LRU list of history of current users.  Most recently current is at the end.
639     */
640    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
641
642    /**
643     * Constant array of the users that are currently started.
644     */
645    int[] mStartedUserArray = new int[] { 0 };
646
647    /**
648     * Registered observers of the user switching mechanics.
649     */
650    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
651            = new RemoteCallbackList<IUserSwitchObserver>();
652
653    /**
654     * Currently active user switch.
655     */
656    Object mCurUserSwitchCallback;
657
658    /**
659     * Packages that the user has asked to have run in screen size
660     * compatibility mode instead of filling the screen.
661     */
662    final CompatModePackages mCompatModePackages;
663
664    /**
665     * Set of IntentSenderRecord objects that are currently active.
666     */
667    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
668            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
669
670    /**
671     * Fingerprints (hashCode()) of stack traces that we've
672     * already logged DropBox entries for.  Guarded by itself.  If
673     * something (rogue user app) forces this over
674     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
675     */
676    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
677    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
678
679    /**
680     * Strict Mode background batched logging state.
681     *
682     * The string buffer is guarded by itself, and its lock is also
683     * used to determine if another batched write is already
684     * in-flight.
685     */
686    private final StringBuilder mStrictModeBuffer = new StringBuilder();
687
688    /**
689     * Keeps track of all IIntentReceivers that have been registered for
690     * broadcasts.  Hash keys are the receiver IBinder, hash value is
691     * a ReceiverList.
692     */
693    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
694            new HashMap<IBinder, ReceiverList>();
695
696    /**
697     * Resolver for broadcast intents to registered receivers.
698     * Holds BroadcastFilter (subclass of IntentFilter).
699     */
700    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
701            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
702        @Override
703        protected boolean allowFilterResult(
704                BroadcastFilter filter, List<BroadcastFilter> dest) {
705            IBinder target = filter.receiverList.receiver.asBinder();
706            for (int i=dest.size()-1; i>=0; i--) {
707                if (dest.get(i).receiverList.receiver.asBinder() == target) {
708                    return false;
709                }
710            }
711            return true;
712        }
713
714        @Override
715        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
716            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
717                    || userId == filter.owningUserId) {
718                return super.newResult(filter, match, userId);
719            }
720            return null;
721        }
722
723        @Override
724        protected BroadcastFilter[] newArray(int size) {
725            return new BroadcastFilter[size];
726        }
727
728        @Override
729        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
730            return packageName.equals(filter.packageName);
731        }
732    };
733
734    /**
735     * State of all active sticky broadcasts per user.  Keys are the action of the
736     * sticky Intent, values are an ArrayList of all broadcasted intents with
737     * that action (which should usually be one).  The SparseArray is keyed
738     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
739     * for stickies that are sent to all users.
740     */
741    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
742            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
743
744    final ActiveServices mServices;
745
746    final static class Association {
747        final int mSourceUid;
748        final String mSourceProcess;
749        final int mTargetUid;
750        final ComponentName mTargetComponent;
751        final String mTargetProcess;
752
753        int mCount;
754        long mTime;
755
756        int mNesting;
757        long mStartTime;
758
759        Association(int sourceUid, String sourceProcess, int targetUid,
760                ComponentName targetComponent, String targetProcess) {
761            mSourceUid = sourceUid;
762            mSourceProcess = sourceProcess;
763            mTargetUid = targetUid;
764            mTargetComponent = targetComponent;
765            mTargetProcess = targetProcess;
766        }
767    }
768
769    /**
770     * When service association tracking is enabled, this is all of the associations we
771     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
772     * -> association data.
773     */
774    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
775            mAssociations = new SparseArray<>();
776    boolean mTrackingAssociations;
777
778    /**
779     * Backup/restore process management
780     */
781    String mBackupAppName = null;
782    BackupRecord mBackupTarget = null;
783
784    final ProviderMap mProviderMap;
785
786    /**
787     * List of content providers who have clients waiting for them.  The
788     * application is currently being launched and the provider will be
789     * removed from this list once it is published.
790     */
791    final ArrayList<ContentProviderRecord> mLaunchingProviders
792            = new ArrayList<ContentProviderRecord>();
793
794    /**
795     * File storing persisted {@link #mGrantedUriPermissions}.
796     */
797    private final AtomicFile mGrantFile;
798
799    /** XML constants used in {@link #mGrantFile} */
800    private static final String TAG_URI_GRANTS = "uri-grants";
801    private static final String TAG_URI_GRANT = "uri-grant";
802    private static final String ATTR_USER_HANDLE = "userHandle";
803    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
804    private static final String ATTR_TARGET_USER_ID = "targetUserId";
805    private static final String ATTR_SOURCE_PKG = "sourcePkg";
806    private static final String ATTR_TARGET_PKG = "targetPkg";
807    private static final String ATTR_URI = "uri";
808    private static final String ATTR_MODE_FLAGS = "modeFlags";
809    private static final String ATTR_CREATED_TIME = "createdTime";
810    private static final String ATTR_PREFIX = "prefix";
811
812    /**
813     * Global set of specific {@link Uri} permissions that have been granted.
814     * This optimized lookup structure maps from {@link UriPermission#targetUid}
815     * to {@link UriPermission#uri} to {@link UriPermission}.
816     */
817    @GuardedBy("this")
818    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
819            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
820
821    public static class GrantUri {
822        public final int sourceUserId;
823        public final Uri uri;
824        public boolean prefix;
825
826        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
827            this.sourceUserId = sourceUserId;
828            this.uri = uri;
829            this.prefix = prefix;
830        }
831
832        @Override
833        public int hashCode() {
834            int hashCode = 1;
835            hashCode = 31 * hashCode + sourceUserId;
836            hashCode = 31 * hashCode + uri.hashCode();
837            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
838            return hashCode;
839        }
840
841        @Override
842        public boolean equals(Object o) {
843            if (o instanceof GrantUri) {
844                GrantUri other = (GrantUri) o;
845                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
846                        && prefix == other.prefix;
847            }
848            return false;
849        }
850
851        @Override
852        public String toString() {
853            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
854            if (prefix) result += " [prefix]";
855            return result;
856        }
857
858        public String toSafeString() {
859            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
860            if (prefix) result += " [prefix]";
861            return result;
862        }
863
864        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
865            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
866                    ContentProvider.getUriWithoutUserId(uri), false);
867        }
868    }
869
870    CoreSettingsObserver mCoreSettingsObserver;
871
872    /**
873     * Thread-local storage used to carry caller permissions over through
874     * indirect content-provider access.
875     */
876    private class Identity {
877        public final IBinder token;
878        public final int pid;
879        public final int uid;
880
881        Identity(IBinder _token, int _pid, int _uid) {
882            token = _token;
883            pid = _pid;
884            uid = _uid;
885        }
886    }
887
888    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
889
890    /**
891     * All information we have collected about the runtime performance of
892     * any user id that can impact battery performance.
893     */
894    final BatteryStatsService mBatteryStatsService;
895
896    /**
897     * Information about component usage
898     */
899    UsageStatsManagerInternal mUsageStatsService;
900
901    /**
902     * Information about and control over application operations
903     */
904    final AppOpsService mAppOpsService;
905
906    /**
907     * Save recent tasks information across reboots.
908     */
909    final TaskPersister mTaskPersister;
910
911    /**
912     * Current configuration information.  HistoryRecord objects are given
913     * a reference to this object to indicate which configuration they are
914     * currently running in, so this object must be kept immutable.
915     */
916    Configuration mConfiguration = new Configuration();
917
918    /**
919     * Current sequencing integer of the configuration, for skipping old
920     * configurations.
921     */
922    int mConfigurationSeq = 0;
923
924    /**
925     * Hardware-reported OpenGLES version.
926     */
927    final int GL_ES_VERSION;
928
929    /**
930     * List of initialization arguments to pass to all processes when binding applications to them.
931     * For example, references to the commonly used services.
932     */
933    HashMap<String, IBinder> mAppBindArgs;
934
935    /**
936     * Temporary to avoid allocations.  Protected by main lock.
937     */
938    final StringBuilder mStringBuilder = new StringBuilder(256);
939
940    /**
941     * Used to control how we initialize the service.
942     */
943    ComponentName mTopComponent;
944    String mTopAction = Intent.ACTION_MAIN;
945    String mTopData;
946    boolean mProcessesReady = false;
947    boolean mSystemReady = false;
948    boolean mBooting = false;
949    boolean mCallFinishBooting = false;
950    boolean mBootAnimationComplete = false;
951    boolean mWaitingUpdate = false;
952    boolean mDidUpdate = false;
953    boolean mOnBattery = false;
954    boolean mLaunchWarningShown = false;
955
956    Context mContext;
957
958    int mFactoryTest;
959
960    boolean mCheckedForSetup;
961
962    /**
963     * The time at which we will allow normal application switches again,
964     * after a call to {@link #stopAppSwitches()}.
965     */
966    long mAppSwitchesAllowedTime;
967
968    /**
969     * This is set to true after the first switch after mAppSwitchesAllowedTime
970     * is set; any switches after that will clear the time.
971     */
972    boolean mDidAppSwitch;
973
974    /**
975     * Last time (in realtime) at which we checked for power usage.
976     */
977    long mLastPowerCheckRealtime;
978
979    /**
980     * Last time (in uptime) at which we checked for power usage.
981     */
982    long mLastPowerCheckUptime;
983
984    /**
985     * Set while we are wanting to sleep, to prevent any
986     * activities from being started/resumed.
987     */
988    private boolean mSleeping = false;
989
990    /**
991     * Set while we are running a voice interaction.  This overrides
992     * sleeping while it is active.
993     */
994    private boolean mRunningVoice = false;
995
996    /**
997     * State of external calls telling us if the device is awake or asleep.
998     */
999    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1000
1001    static final int LOCK_SCREEN_HIDDEN = 0;
1002    static final int LOCK_SCREEN_LEAVING = 1;
1003    static final int LOCK_SCREEN_SHOWN = 2;
1004    /**
1005     * State of external call telling us if the lock screen is shown.
1006     */
1007    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1008
1009    /**
1010     * Set if we are shutting down the system, similar to sleeping.
1011     */
1012    boolean mShuttingDown = false;
1013
1014    /**
1015     * Current sequence id for oom_adj computation traversal.
1016     */
1017    int mAdjSeq = 0;
1018
1019    /**
1020     * Current sequence id for process LRU updating.
1021     */
1022    int mLruSeq = 0;
1023
1024    /**
1025     * Keep track of the non-cached/empty process we last found, to help
1026     * determine how to distribute cached/empty processes next time.
1027     */
1028    int mNumNonCachedProcs = 0;
1029
1030    /**
1031     * Keep track of the number of cached hidden procs, to balance oom adj
1032     * distribution between those and empty procs.
1033     */
1034    int mNumCachedHiddenProcs = 0;
1035
1036    /**
1037     * Keep track of the number of service processes we last found, to
1038     * determine on the next iteration which should be B services.
1039     */
1040    int mNumServiceProcs = 0;
1041    int mNewNumAServiceProcs = 0;
1042    int mNewNumServiceProcs = 0;
1043
1044    /**
1045     * Allow the current computed overall memory level of the system to go down?
1046     * This is set to false when we are killing processes for reasons other than
1047     * memory management, so that the now smaller process list will not be taken as
1048     * an indication that memory is tighter.
1049     */
1050    boolean mAllowLowerMemLevel = false;
1051
1052    /**
1053     * The last computed memory level, for holding when we are in a state that
1054     * processes are going away for other reasons.
1055     */
1056    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1057
1058    /**
1059     * The last total number of process we have, to determine if changes actually look
1060     * like a shrinking number of process due to lower RAM.
1061     */
1062    int mLastNumProcesses;
1063
1064    /**
1065     * The uptime of the last time we performed idle maintenance.
1066     */
1067    long mLastIdleTime = SystemClock.uptimeMillis();
1068
1069    /**
1070     * Total time spent with RAM that has been added in the past since the last idle time.
1071     */
1072    long mLowRamTimeSinceLastIdle = 0;
1073
1074    /**
1075     * If RAM is currently low, when that horrible situation started.
1076     */
1077    long mLowRamStartTime = 0;
1078
1079    /**
1080     * For reporting to battery stats the current top application.
1081     */
1082    private String mCurResumedPackage = null;
1083    private int mCurResumedUid = -1;
1084
1085    /**
1086     * For reporting to battery stats the apps currently running foreground
1087     * service.  The ProcessMap is package/uid tuples; each of these contain
1088     * an array of the currently foreground processes.
1089     */
1090    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1091            = new ProcessMap<ArrayList<ProcessRecord>>();
1092
1093    /**
1094     * This is set if we had to do a delayed dexopt of an app before launching
1095     * it, to increase the ANR timeouts in that case.
1096     */
1097    boolean mDidDexOpt;
1098
1099    /**
1100     * Set if the systemServer made a call to enterSafeMode.
1101     */
1102    boolean mSafeMode;
1103
1104    /**
1105     * If true, we are running under a test environment so will sample PSS from processes
1106     * much more rapidly to try to collect better data when the tests are rapidly
1107     * running through apps.
1108     */
1109    boolean mTestPssMode = false;
1110
1111    String mDebugApp = null;
1112    boolean mWaitForDebugger = false;
1113    boolean mDebugTransient = false;
1114    String mOrigDebugApp = null;
1115    boolean mOrigWaitForDebugger = false;
1116    boolean mAlwaysFinishActivities = false;
1117    IActivityController mController = null;
1118    String mProfileApp = null;
1119    ProcessRecord mProfileProc = null;
1120    String mProfileFile;
1121    ParcelFileDescriptor mProfileFd;
1122    int mSamplingInterval = 0;
1123    boolean mAutoStopProfiler = false;
1124    int mProfileType = 0;
1125    String mOpenGlTraceApp = null;
1126    final ArrayMap<String, Long> mMemWatchProcesses = new ArrayMap<>();
1127    String mMemWatchDumpProcName;
1128    String mMemWatchDumpFile;
1129    int mMemWatchDumpPid;
1130    int mMemWatchDumpUid;
1131
1132    final long[] mTmpLong = new long[1];
1133
1134    static class ProcessChangeItem {
1135        static final int CHANGE_ACTIVITIES = 1<<0;
1136        static final int CHANGE_PROCESS_STATE = 1<<1;
1137        int changes;
1138        int uid;
1139        int pid;
1140        int processState;
1141        boolean foregroundActivities;
1142    }
1143
1144    final RemoteCallbackList<IProcessObserver> mProcessObservers
1145            = new RemoteCallbackList<IProcessObserver>();
1146    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1147
1148    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1149            = new ArrayList<ProcessChangeItem>();
1150    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1151            = new ArrayList<ProcessChangeItem>();
1152
1153    /**
1154     * Runtime CPU use collection thread.  This object's lock is used to
1155     * perform synchronization with the thread (notifying it to run).
1156     */
1157    final Thread mProcessCpuThread;
1158
1159    /**
1160     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1161     * Must acquire this object's lock when accessing it.
1162     * NOTE: this lock will be held while doing long operations (trawling
1163     * through all processes in /proc), so it should never be acquired by
1164     * any critical paths such as when holding the main activity manager lock.
1165     */
1166    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1167            MONITOR_THREAD_CPU_USAGE);
1168    final AtomicLong mLastCpuTime = new AtomicLong(0);
1169    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1170
1171    long mLastWriteTime = 0;
1172
1173    /**
1174     * Used to retain an update lock when the foreground activity is in
1175     * immersive mode.
1176     */
1177    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1178
1179    /**
1180     * Set to true after the system has finished booting.
1181     */
1182    boolean mBooted = false;
1183
1184    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1185    int mProcessLimitOverride = -1;
1186
1187    WindowManagerService mWindowManager;
1188
1189    final ActivityThread mSystemThread;
1190
1191    // Holds the current foreground user's id
1192    int mCurrentUserId = 0;
1193    // Holds the target user's id during a user switch
1194    int mTargetUserId = UserHandle.USER_NULL;
1195    // If there are multiple profiles for the current user, their ids are here
1196    // Currently only the primary user can have managed profiles
1197    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1198
1199    /**
1200     * Mapping from each known user ID to the profile group ID it is associated with.
1201     */
1202    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1203
1204    private UserManagerService mUserManager;
1205
1206    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1207        final ProcessRecord mApp;
1208        final int mPid;
1209        final IApplicationThread mAppThread;
1210
1211        AppDeathRecipient(ProcessRecord app, int pid,
1212                IApplicationThread thread) {
1213            if (DEBUG_ALL) Slog.v(
1214                TAG, "New death recipient " + this
1215                + " for thread " + thread.asBinder());
1216            mApp = app;
1217            mPid = pid;
1218            mAppThread = thread;
1219        }
1220
1221        @Override
1222        public void binderDied() {
1223            if (DEBUG_ALL) Slog.v(
1224                TAG, "Death received in " + this
1225                + " for thread " + mAppThread.asBinder());
1226            synchronized(ActivityManagerService.this) {
1227                appDiedLocked(mApp, mPid, mAppThread);
1228            }
1229        }
1230    }
1231
1232    static final int SHOW_ERROR_MSG = 1;
1233    static final int SHOW_NOT_RESPONDING_MSG = 2;
1234    static final int SHOW_FACTORY_ERROR_MSG = 3;
1235    static final int UPDATE_CONFIGURATION_MSG = 4;
1236    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1237    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1238    static final int SERVICE_TIMEOUT_MSG = 12;
1239    static final int UPDATE_TIME_ZONE = 13;
1240    static final int SHOW_UID_ERROR_MSG = 14;
1241    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1242    static final int PROC_START_TIMEOUT_MSG = 20;
1243    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1244    static final int KILL_APPLICATION_MSG = 22;
1245    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1246    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1247    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1248    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1249    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1250    static final int CLEAR_DNS_CACHE_MSG = 28;
1251    static final int UPDATE_HTTP_PROXY_MSG = 29;
1252    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1253    static final int DISPATCH_PROCESSES_CHANGED = 31;
1254    static final int DISPATCH_PROCESS_DIED = 32;
1255    static final int REPORT_MEM_USAGE_MSG = 33;
1256    static final int REPORT_USER_SWITCH_MSG = 34;
1257    static final int CONTINUE_USER_SWITCH_MSG = 35;
1258    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1259    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1260    static final int PERSIST_URI_GRANTS_MSG = 38;
1261    static final int REQUEST_ALL_PSS_MSG = 39;
1262    static final int START_PROFILES_MSG = 40;
1263    static final int UPDATE_TIME = 41;
1264    static final int SYSTEM_USER_START_MSG = 42;
1265    static final int SYSTEM_USER_CURRENT_MSG = 43;
1266    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1267    static final int FINISH_BOOTING_MSG = 45;
1268    static final int START_USER_SWITCH_MSG = 46;
1269    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1270    static final int DISMISS_DIALOG_MSG = 48;
1271    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1272    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1273    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1274    static final int DELETE_DUMPHEAP_MSG = 52;
1275
1276    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1277    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1278    static final int FIRST_COMPAT_MODE_MSG = 300;
1279    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1280
1281    CompatModeDialog mCompatModeDialog;
1282    long mLastMemUsageReportTime = 0;
1283
1284    /**
1285     * Flag whether the current user is a "monkey", i.e. whether
1286     * the UI is driven by a UI automation tool.
1287     */
1288    private boolean mUserIsMonkey;
1289
1290    /** Flag whether the device has a Recents UI */
1291    boolean mHasRecents;
1292
1293    /** The dimensions of the thumbnails in the Recents UI. */
1294    int mThumbnailWidth;
1295    int mThumbnailHeight;
1296
1297    final ServiceThread mHandlerThread;
1298    final MainHandler mHandler;
1299
1300    final class MainHandler extends Handler {
1301        public MainHandler(Looper looper) {
1302            super(looper, null, true);
1303        }
1304
1305        @Override
1306        public void handleMessage(Message msg) {
1307            switch (msg.what) {
1308            case SHOW_ERROR_MSG: {
1309                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1310                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1311                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1312                synchronized (ActivityManagerService.this) {
1313                    ProcessRecord proc = (ProcessRecord)data.get("app");
1314                    AppErrorResult res = (AppErrorResult) data.get("result");
1315                    if (proc != null && proc.crashDialog != null) {
1316                        Slog.e(TAG, "App already has crash dialog: " + proc);
1317                        if (res != null) {
1318                            res.set(0);
1319                        }
1320                        return;
1321                    }
1322                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1323                            >= Process.FIRST_APPLICATION_UID
1324                            && proc.pid != MY_PID);
1325                    for (int userId : mCurrentProfileIds) {
1326                        isBackground &= (proc.userId != userId);
1327                    }
1328                    if (isBackground && !showBackground) {
1329                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1330                        if (res != null) {
1331                            res.set(0);
1332                        }
1333                        return;
1334                    }
1335                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1336                        Dialog d = new AppErrorDialog(mContext,
1337                                ActivityManagerService.this, res, proc);
1338                        d.show();
1339                        proc.crashDialog = d;
1340                    } else {
1341                        // The device is asleep, so just pretend that the user
1342                        // saw a crash dialog and hit "force quit".
1343                        if (res != null) {
1344                            res.set(0);
1345                        }
1346                    }
1347                }
1348
1349                ensureBootCompleted();
1350            } break;
1351            case SHOW_NOT_RESPONDING_MSG: {
1352                synchronized (ActivityManagerService.this) {
1353                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1354                    ProcessRecord proc = (ProcessRecord)data.get("app");
1355                    if (proc != null && proc.anrDialog != null) {
1356                        Slog.e(TAG, "App already has anr dialog: " + proc);
1357                        return;
1358                    }
1359
1360                    Intent intent = new Intent("android.intent.action.ANR");
1361                    if (!mProcessesReady) {
1362                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1363                                | Intent.FLAG_RECEIVER_FOREGROUND);
1364                    }
1365                    broadcastIntentLocked(null, null, intent,
1366                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1367                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1368
1369                    if (mShowDialogs) {
1370                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1371                                mContext, proc, (ActivityRecord)data.get("activity"),
1372                                msg.arg1 != 0);
1373                        d.show();
1374                        proc.anrDialog = d;
1375                    } else {
1376                        // Just kill the app if there is no dialog to be shown.
1377                        killAppAtUsersRequest(proc, null);
1378                    }
1379                }
1380
1381                ensureBootCompleted();
1382            } break;
1383            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1384                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1385                synchronized (ActivityManagerService.this) {
1386                    ProcessRecord proc = (ProcessRecord) data.get("app");
1387                    if (proc == null) {
1388                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1389                        break;
1390                    }
1391                    if (proc.crashDialog != null) {
1392                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1393                        return;
1394                    }
1395                    AppErrorResult res = (AppErrorResult) data.get("result");
1396                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1397                        Dialog d = new StrictModeViolationDialog(mContext,
1398                                ActivityManagerService.this, res, proc);
1399                        d.show();
1400                        proc.crashDialog = d;
1401                    } else {
1402                        // The device is asleep, so just pretend that the user
1403                        // saw a crash dialog and hit "force quit".
1404                        res.set(0);
1405                    }
1406                }
1407                ensureBootCompleted();
1408            } break;
1409            case SHOW_FACTORY_ERROR_MSG: {
1410                Dialog d = new FactoryErrorDialog(
1411                    mContext, msg.getData().getCharSequence("msg"));
1412                d.show();
1413                ensureBootCompleted();
1414            } break;
1415            case UPDATE_CONFIGURATION_MSG: {
1416                final ContentResolver resolver = mContext.getContentResolver();
1417                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1418            } break;
1419            case GC_BACKGROUND_PROCESSES_MSG: {
1420                synchronized (ActivityManagerService.this) {
1421                    performAppGcsIfAppropriateLocked();
1422                }
1423            } break;
1424            case WAIT_FOR_DEBUGGER_MSG: {
1425                synchronized (ActivityManagerService.this) {
1426                    ProcessRecord app = (ProcessRecord)msg.obj;
1427                    if (msg.arg1 != 0) {
1428                        if (!app.waitedForDebugger) {
1429                            Dialog d = new AppWaitingForDebuggerDialog(
1430                                    ActivityManagerService.this,
1431                                    mContext, app);
1432                            app.waitDialog = d;
1433                            app.waitedForDebugger = true;
1434                            d.show();
1435                        }
1436                    } else {
1437                        if (app.waitDialog != null) {
1438                            app.waitDialog.dismiss();
1439                            app.waitDialog = null;
1440                        }
1441                    }
1442                }
1443            } break;
1444            case SERVICE_TIMEOUT_MSG: {
1445                if (mDidDexOpt) {
1446                    mDidDexOpt = false;
1447                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1448                    nmsg.obj = msg.obj;
1449                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1450                    return;
1451                }
1452                mServices.serviceTimeout((ProcessRecord)msg.obj);
1453            } break;
1454            case UPDATE_TIME_ZONE: {
1455                synchronized (ActivityManagerService.this) {
1456                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1457                        ProcessRecord r = mLruProcesses.get(i);
1458                        if (r.thread != null) {
1459                            try {
1460                                r.thread.updateTimeZone();
1461                            } catch (RemoteException ex) {
1462                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1463                            }
1464                        }
1465                    }
1466                }
1467            } break;
1468            case CLEAR_DNS_CACHE_MSG: {
1469                synchronized (ActivityManagerService.this) {
1470                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1471                        ProcessRecord r = mLruProcesses.get(i);
1472                        if (r.thread != null) {
1473                            try {
1474                                r.thread.clearDnsCache();
1475                            } catch (RemoteException ex) {
1476                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1477                            }
1478                        }
1479                    }
1480                }
1481            } break;
1482            case UPDATE_HTTP_PROXY_MSG: {
1483                ProxyInfo proxy = (ProxyInfo)msg.obj;
1484                String host = "";
1485                String port = "";
1486                String exclList = "";
1487                Uri pacFileUrl = Uri.EMPTY;
1488                if (proxy != null) {
1489                    host = proxy.getHost();
1490                    port = Integer.toString(proxy.getPort());
1491                    exclList = proxy.getExclusionListAsString();
1492                    pacFileUrl = proxy.getPacFileUrl();
1493                }
1494                synchronized (ActivityManagerService.this) {
1495                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1496                        ProcessRecord r = mLruProcesses.get(i);
1497                        if (r.thread != null) {
1498                            try {
1499                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1500                            } catch (RemoteException ex) {
1501                                Slog.w(TAG, "Failed to update http proxy for: " +
1502                                        r.info.processName);
1503                            }
1504                        }
1505                    }
1506                }
1507            } break;
1508            case SHOW_UID_ERROR_MSG: {
1509                if (mShowDialogs) {
1510                    AlertDialog d = new BaseErrorDialog(mContext);
1511                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1512                    d.setCancelable(false);
1513                    d.setTitle(mContext.getText(R.string.android_system_label));
1514                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1515                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1516                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1517                    d.show();
1518                }
1519            } break;
1520            case SHOW_FINGERPRINT_ERROR_MSG: {
1521                if (mShowDialogs) {
1522                    AlertDialog d = new BaseErrorDialog(mContext);
1523                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1524                    d.setCancelable(false);
1525                    d.setTitle(mContext.getText(R.string.android_system_label));
1526                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1527                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1528                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1529                    d.show();
1530                }
1531            } break;
1532            case PROC_START_TIMEOUT_MSG: {
1533                if (mDidDexOpt) {
1534                    mDidDexOpt = false;
1535                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1536                    nmsg.obj = msg.obj;
1537                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1538                    return;
1539                }
1540                ProcessRecord app = (ProcessRecord)msg.obj;
1541                synchronized (ActivityManagerService.this) {
1542                    processStartTimedOutLocked(app);
1543                }
1544            } break;
1545            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1546                synchronized (ActivityManagerService.this) {
1547                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1548                }
1549            } break;
1550            case KILL_APPLICATION_MSG: {
1551                synchronized (ActivityManagerService.this) {
1552                    int appid = msg.arg1;
1553                    boolean restart = (msg.arg2 == 1);
1554                    Bundle bundle = (Bundle)msg.obj;
1555                    String pkg = bundle.getString("pkg");
1556                    String reason = bundle.getString("reason");
1557                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1558                            false, UserHandle.USER_ALL, reason);
1559                }
1560            } break;
1561            case FINALIZE_PENDING_INTENT_MSG: {
1562                ((PendingIntentRecord)msg.obj).completeFinalize();
1563            } break;
1564            case POST_HEAVY_NOTIFICATION_MSG: {
1565                INotificationManager inm = NotificationManager.getService();
1566                if (inm == null) {
1567                    return;
1568                }
1569
1570                ActivityRecord root = (ActivityRecord)msg.obj;
1571                ProcessRecord process = root.app;
1572                if (process == null) {
1573                    return;
1574                }
1575
1576                try {
1577                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1578                    String text = mContext.getString(R.string.heavy_weight_notification,
1579                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1580                    Notification notification = new Notification();
1581                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1582                    notification.when = 0;
1583                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1584                    notification.tickerText = text;
1585                    notification.defaults = 0; // please be quiet
1586                    notification.sound = null;
1587                    notification.vibrate = null;
1588                    notification.color = mContext.getResources().getColor(
1589                            com.android.internal.R.color.system_notification_accent_color);
1590                    notification.setLatestEventInfo(context, text,
1591                            mContext.getText(R.string.heavy_weight_notification_detail),
1592                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1593                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1594                                    new UserHandle(root.userId)));
1595
1596                    try {
1597                        int[] outId = new int[1];
1598                        inm.enqueueNotificationWithTag("android", "android", null,
1599                                R.string.heavy_weight_notification,
1600                                notification, outId, root.userId);
1601                    } catch (RuntimeException e) {
1602                        Slog.w(ActivityManagerService.TAG,
1603                                "Error showing notification for heavy-weight app", e);
1604                    } catch (RemoteException e) {
1605                    }
1606                } catch (NameNotFoundException e) {
1607                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1608                }
1609            } break;
1610            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1611                INotificationManager inm = NotificationManager.getService();
1612                if (inm == null) {
1613                    return;
1614                }
1615                try {
1616                    inm.cancelNotificationWithTag("android", null,
1617                            R.string.heavy_weight_notification,  msg.arg1);
1618                } catch (RuntimeException e) {
1619                    Slog.w(ActivityManagerService.TAG,
1620                            "Error canceling notification for service", e);
1621                } catch (RemoteException e) {
1622                }
1623            } break;
1624            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1625                synchronized (ActivityManagerService.this) {
1626                    checkExcessivePowerUsageLocked(true);
1627                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1628                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1629                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1630                }
1631            } break;
1632            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1633                synchronized (ActivityManagerService.this) {
1634                    ActivityRecord ar = (ActivityRecord)msg.obj;
1635                    if (mCompatModeDialog != null) {
1636                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1637                                ar.info.applicationInfo.packageName)) {
1638                            return;
1639                        }
1640                        mCompatModeDialog.dismiss();
1641                        mCompatModeDialog = null;
1642                    }
1643                    if (ar != null && false) {
1644                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1645                                ar.packageName)) {
1646                            int mode = mCompatModePackages.computeCompatModeLocked(
1647                                    ar.info.applicationInfo);
1648                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1649                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1650                                mCompatModeDialog = new CompatModeDialog(
1651                                        ActivityManagerService.this, mContext,
1652                                        ar.info.applicationInfo);
1653                                mCompatModeDialog.show();
1654                            }
1655                        }
1656                    }
1657                }
1658                break;
1659            }
1660            case DISPATCH_PROCESSES_CHANGED: {
1661                dispatchProcessesChanged();
1662                break;
1663            }
1664            case DISPATCH_PROCESS_DIED: {
1665                final int pid = msg.arg1;
1666                final int uid = msg.arg2;
1667                dispatchProcessDied(pid, uid);
1668                break;
1669            }
1670            case REPORT_MEM_USAGE_MSG: {
1671                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1672                Thread thread = new Thread() {
1673                    @Override public void run() {
1674                        reportMemUsage(memInfos);
1675                    }
1676                };
1677                thread.start();
1678                break;
1679            }
1680            case START_USER_SWITCH_MSG: {
1681                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1682                break;
1683            }
1684            case REPORT_USER_SWITCH_MSG: {
1685                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1686                break;
1687            }
1688            case CONTINUE_USER_SWITCH_MSG: {
1689                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1690                break;
1691            }
1692            case USER_SWITCH_TIMEOUT_MSG: {
1693                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1694                break;
1695            }
1696            case IMMERSIVE_MODE_LOCK_MSG: {
1697                final boolean nextState = (msg.arg1 != 0);
1698                if (mUpdateLock.isHeld() != nextState) {
1699                    if (DEBUG_IMMERSIVE) {
1700                        final ActivityRecord r = (ActivityRecord) msg.obj;
1701                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1702                    }
1703                    if (nextState) {
1704                        mUpdateLock.acquire();
1705                    } else {
1706                        mUpdateLock.release();
1707                    }
1708                }
1709                break;
1710            }
1711            case PERSIST_URI_GRANTS_MSG: {
1712                writeGrantedUriPermissions();
1713                break;
1714            }
1715            case REQUEST_ALL_PSS_MSG: {
1716                synchronized (ActivityManagerService.this) {
1717                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1718                }
1719                break;
1720            }
1721            case START_PROFILES_MSG: {
1722                synchronized (ActivityManagerService.this) {
1723                    startProfilesLocked();
1724                }
1725                break;
1726            }
1727            case UPDATE_TIME: {
1728                synchronized (ActivityManagerService.this) {
1729                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1730                        ProcessRecord r = mLruProcesses.get(i);
1731                        if (r.thread != null) {
1732                            try {
1733                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1734                            } catch (RemoteException ex) {
1735                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1736                            }
1737                        }
1738                    }
1739                }
1740                break;
1741            }
1742            case SYSTEM_USER_START_MSG: {
1743                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1744                        Integer.toString(msg.arg1), msg.arg1);
1745                mSystemServiceManager.startUser(msg.arg1);
1746                break;
1747            }
1748            case SYSTEM_USER_CURRENT_MSG: {
1749                mBatteryStatsService.noteEvent(
1750                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1751                        Integer.toString(msg.arg2), msg.arg2);
1752                mBatteryStatsService.noteEvent(
1753                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1754                        Integer.toString(msg.arg1), msg.arg1);
1755                mSystemServiceManager.switchUser(msg.arg1);
1756                break;
1757            }
1758            case ENTER_ANIMATION_COMPLETE_MSG: {
1759                synchronized (ActivityManagerService.this) {
1760                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1761                    if (r != null && r.app != null && r.app.thread != null) {
1762                        try {
1763                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1764                        } catch (RemoteException e) {
1765                        }
1766                    }
1767                }
1768                break;
1769            }
1770            case FINISH_BOOTING_MSG: {
1771                if (msg.arg1 != 0) {
1772                    finishBooting();
1773                }
1774                if (msg.arg2 != 0) {
1775                    enableScreenAfterBoot();
1776                }
1777                break;
1778            }
1779            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1780                try {
1781                    Locale l = (Locale) msg.obj;
1782                    IBinder service = ServiceManager.getService("mount");
1783                    IMountService mountService = IMountService.Stub.asInterface(service);
1784                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1785                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1786                } catch (RemoteException e) {
1787                    Log.e(TAG, "Error storing locale for decryption UI", e);
1788                }
1789                break;
1790            }
1791            case DISMISS_DIALOG_MSG: {
1792                final Dialog d = (Dialog) msg.obj;
1793                d.dismiss();
1794                break;
1795            }
1796            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1797                synchronized (ActivityManagerService.this) {
1798                    int i = mTaskStackListeners.beginBroadcast();
1799                    while (i > 0) {
1800                        i--;
1801                        try {
1802                            // Make a one-way callback to the listener
1803                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1804                        } catch (RemoteException e){
1805                            // Handled by the RemoteCallbackList
1806                        }
1807                    }
1808                    mTaskStackListeners.finishBroadcast();
1809                }
1810                break;
1811            }
1812            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1813                final int uid = msg.arg1;
1814                final byte[] firstPacket = (byte[]) msg.obj;
1815
1816                synchronized (mPidsSelfLocked) {
1817                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1818                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1819                        if (p.uid == uid) {
1820                            try {
1821                                p.thread.notifyCleartextNetwork(firstPacket);
1822                            } catch (RemoteException ignored) {
1823                            }
1824                        }
1825                    }
1826                }
1827                break;
1828            }
1829            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1830                final String procName;
1831                final int uid;
1832                final long memLimit;
1833                synchronized (ActivityManagerService.this) {
1834                    procName = mMemWatchDumpProcName;
1835                    uid = mMemWatchDumpUid;
1836                    Long limit = mMemWatchProcesses.get(procName);
1837                    memLimit = limit != null ? limit : 0;
1838                }
1839                if (procName == null) {
1840                    return;
1841                }
1842
1843                if (DEBUG_PSS) Slog.d(TAG, "Showing dump heap notification from "
1844                        + procName + "/" + uid);
1845
1846                INotificationManager inm = NotificationManager.getService();
1847                if (inm == null) {
1848                    return;
1849                }
1850
1851                String text = mContext.getString(R.string.dump_heap_notification, procName);
1852                Notification notification = new Notification();
1853                notification.icon = com.android.internal.R.drawable.stat_sys_adb;
1854                notification.when = 0;
1855                notification.flags = Notification.FLAG_ONGOING_EVENT|Notification.FLAG_AUTO_CANCEL;
1856                notification.tickerText = text;
1857                notification.defaults = 0; // please be quiet
1858                notification.sound = null;
1859                notification.vibrate = null;
1860                notification.color = mContext.getResources().getColor(
1861                        com.android.internal.R.color.system_notification_accent_color);
1862                Intent deleteIntent = new Intent();
1863                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1864                notification.deleteIntent = PendingIntent.getBroadcastAsUser(mContext, 0,
1865                        deleteIntent, 0, UserHandle.OWNER);
1866                Intent intent = new Intent();
1867                intent.setClassName("android", DumpHeapActivity.class.getName());
1868                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1869                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1870                int userId = UserHandle.getUserId(uid);
1871                notification.setLatestEventInfo(mContext, text,
1872                        mContext.getText(R.string.dump_heap_notification_detail),
1873                        PendingIntent.getActivityAsUser(mContext, 0, intent,
1874                                PendingIntent.FLAG_CANCEL_CURRENT, null,
1875                                new UserHandle(userId)));
1876
1877                try {
1878                    int[] outId = new int[1];
1879                    inm.enqueueNotificationWithTag("android", "android", null,
1880                            R.string.dump_heap_notification,
1881                            notification, outId, userId);
1882                } catch (RuntimeException e) {
1883                    Slog.w(ActivityManagerService.TAG,
1884                            "Error showing notification for dump heap", e);
1885                } catch (RemoteException e) {
1886                }
1887            } break;
1888            case DELETE_DUMPHEAP_MSG: {
1889                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
1890                        DumpHeapActivity.JAVA_URI,
1891                        Intent.FLAG_GRANT_READ_URI_PERMISSION
1892                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
1893                        UserHandle.myUserId());
1894                synchronized (ActivityManagerService.this) {
1895                    mMemWatchDumpFile = null;
1896                    mMemWatchDumpProcName = null;
1897                    mMemWatchDumpPid = -1;
1898                    mMemWatchDumpUid = -1;
1899                }
1900            } break;
1901            }
1902        }
1903    };
1904
1905    static final int COLLECT_PSS_BG_MSG = 1;
1906
1907    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1908        @Override
1909        public void handleMessage(Message msg) {
1910            switch (msg.what) {
1911            case COLLECT_PSS_BG_MSG: {
1912                long start = SystemClock.uptimeMillis();
1913                MemInfoReader memInfo = null;
1914                synchronized (ActivityManagerService.this) {
1915                    if (mFullPssPending) {
1916                        mFullPssPending = false;
1917                        memInfo = new MemInfoReader();
1918                    }
1919                }
1920                if (memInfo != null) {
1921                    updateCpuStatsNow();
1922                    long nativeTotalPss = 0;
1923                    synchronized (mProcessCpuTracker) {
1924                        final int N = mProcessCpuTracker.countStats();
1925                        for (int j=0; j<N; j++) {
1926                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1927                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1928                                // This is definitely an application process; skip it.
1929                                continue;
1930                            }
1931                            synchronized (mPidsSelfLocked) {
1932                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1933                                    // This is one of our own processes; skip it.
1934                                    continue;
1935                                }
1936                            }
1937                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1938                        }
1939                    }
1940                    memInfo.readMemInfo();
1941                    synchronized (ActivityManagerService.this) {
1942                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1943                                + (SystemClock.uptimeMillis()-start) + "ms");
1944                        final long cachedKb = memInfo.getCachedSizeKb();
1945                        final long freeKb = memInfo.getFreeSizeKb();
1946                        final long zramKb = memInfo.getZramTotalSizeKb();
1947                        final long kernelKb = memInfo.getKernelUsedSizeKb();
1948                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
1949                                kernelKb*1024, nativeTotalPss*1024);
1950                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
1951                                nativeTotalPss);
1952                    }
1953                }
1954
1955                int num = 0;
1956                long[] tmp = new long[1];
1957                do {
1958                    ProcessRecord proc;
1959                    int procState;
1960                    int pid;
1961                    long lastPssTime;
1962                    synchronized (ActivityManagerService.this) {
1963                        if (mPendingPssProcesses.size() <= 0) {
1964                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1965                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1966                            mPendingPssProcesses.clear();
1967                            return;
1968                        }
1969                        proc = mPendingPssProcesses.remove(0);
1970                        procState = proc.pssProcState;
1971                        lastPssTime = proc.lastPssTime;
1972                        if (proc.thread != null && procState == proc.setProcState
1973                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1974                                        < SystemClock.uptimeMillis()) {
1975                            pid = proc.pid;
1976                        } else {
1977                            proc = null;
1978                            pid = 0;
1979                        }
1980                    }
1981                    if (proc != null) {
1982                        long pss = Debug.getPss(pid, tmp, null);
1983                        synchronized (ActivityManagerService.this) {
1984                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1985                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1986                                num++;
1987                                recordPssSampleLocked(proc, procState, pss, tmp[0],
1988                                        SystemClock.uptimeMillis());
1989                            }
1990                        }
1991                    }
1992                } while (true);
1993            }
1994            }
1995        }
1996    };
1997
1998    public void setSystemProcess() {
1999        try {
2000            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2001            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2002            ServiceManager.addService("meminfo", new MemBinder(this));
2003            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2004            ServiceManager.addService("dbinfo", new DbBinder(this));
2005            if (MONITOR_CPU_USAGE) {
2006                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2007            }
2008            ServiceManager.addService("permission", new PermissionController(this));
2009            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2010
2011            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2012                    "android", STOCK_PM_FLAGS);
2013            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2014
2015            synchronized (this) {
2016                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2017                app.persistent = true;
2018                app.pid = MY_PID;
2019                app.maxAdj = ProcessList.SYSTEM_ADJ;
2020                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2021                mProcessNames.put(app.processName, app.uid, app);
2022                synchronized (mPidsSelfLocked) {
2023                    mPidsSelfLocked.put(app.pid, app);
2024                }
2025                updateLruProcessLocked(app, false, null);
2026                updateOomAdjLocked();
2027            }
2028        } catch (PackageManager.NameNotFoundException e) {
2029            throw new RuntimeException(
2030                    "Unable to find android system package", e);
2031        }
2032    }
2033
2034    public void setWindowManager(WindowManagerService wm) {
2035        mWindowManager = wm;
2036        mStackSupervisor.setWindowManager(wm);
2037    }
2038
2039    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2040        mUsageStatsService = usageStatsManager;
2041    }
2042
2043    public void startObservingNativeCrashes() {
2044        final NativeCrashListener ncl = new NativeCrashListener(this);
2045        ncl.start();
2046    }
2047
2048    public IAppOpsService getAppOpsService() {
2049        return mAppOpsService;
2050    }
2051
2052    static class MemBinder extends Binder {
2053        ActivityManagerService mActivityManagerService;
2054        MemBinder(ActivityManagerService activityManagerService) {
2055            mActivityManagerService = activityManagerService;
2056        }
2057
2058        @Override
2059        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2060            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2061                    != PackageManager.PERMISSION_GRANTED) {
2062                pw.println("Permission Denial: can't dump meminfo from from pid="
2063                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2064                        + " without permission " + android.Manifest.permission.DUMP);
2065                return;
2066            }
2067
2068            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2069        }
2070    }
2071
2072    static class GraphicsBinder extends Binder {
2073        ActivityManagerService mActivityManagerService;
2074        GraphicsBinder(ActivityManagerService activityManagerService) {
2075            mActivityManagerService = activityManagerService;
2076        }
2077
2078        @Override
2079        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2080            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2081                    != PackageManager.PERMISSION_GRANTED) {
2082                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2083                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2084                        + " without permission " + android.Manifest.permission.DUMP);
2085                return;
2086            }
2087
2088            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2089        }
2090    }
2091
2092    static class DbBinder extends Binder {
2093        ActivityManagerService mActivityManagerService;
2094        DbBinder(ActivityManagerService activityManagerService) {
2095            mActivityManagerService = activityManagerService;
2096        }
2097
2098        @Override
2099        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2100            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2101                    != PackageManager.PERMISSION_GRANTED) {
2102                pw.println("Permission Denial: can't dump dbinfo from from pid="
2103                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2104                        + " without permission " + android.Manifest.permission.DUMP);
2105                return;
2106            }
2107
2108            mActivityManagerService.dumpDbInfo(fd, pw, args);
2109        }
2110    }
2111
2112    static class CpuBinder extends Binder {
2113        ActivityManagerService mActivityManagerService;
2114        CpuBinder(ActivityManagerService activityManagerService) {
2115            mActivityManagerService = activityManagerService;
2116        }
2117
2118        @Override
2119        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2120            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2121                    != PackageManager.PERMISSION_GRANTED) {
2122                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2123                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2124                        + " without permission " + android.Manifest.permission.DUMP);
2125                return;
2126            }
2127
2128            synchronized (mActivityManagerService.mProcessCpuTracker) {
2129                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2130                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2131                        SystemClock.uptimeMillis()));
2132            }
2133        }
2134    }
2135
2136    public static final class Lifecycle extends SystemService {
2137        private final ActivityManagerService mService;
2138
2139        public Lifecycle(Context context) {
2140            super(context);
2141            mService = new ActivityManagerService(context);
2142        }
2143
2144        @Override
2145        public void onStart() {
2146            mService.start();
2147        }
2148
2149        public ActivityManagerService getService() {
2150            return mService;
2151        }
2152    }
2153
2154    // Note: This method is invoked on the main thread but may need to attach various
2155    // handlers to other threads.  So take care to be explicit about the looper.
2156    public ActivityManagerService(Context systemContext) {
2157        mContext = systemContext;
2158        mFactoryTest = FactoryTest.getMode();
2159        mSystemThread = ActivityThread.currentActivityThread();
2160
2161        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2162
2163        mHandlerThread = new ServiceThread(TAG,
2164                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2165        mHandlerThread.start();
2166        mHandler = new MainHandler(mHandlerThread.getLooper());
2167
2168        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2169                "foreground", BROADCAST_FG_TIMEOUT, false);
2170        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2171                "background", BROADCAST_BG_TIMEOUT, true);
2172        mBroadcastQueues[0] = mFgBroadcastQueue;
2173        mBroadcastQueues[1] = mBgBroadcastQueue;
2174
2175        mServices = new ActiveServices(this);
2176        mProviderMap = new ProviderMap(this);
2177
2178        // TODO: Move creation of battery stats service outside of activity manager service.
2179        File dataDir = Environment.getDataDirectory();
2180        File systemDir = new File(dataDir, "system");
2181        systemDir.mkdirs();
2182        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2183        mBatteryStatsService.getActiveStatistics().readLocked();
2184        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2185        mOnBattery = DEBUG_POWER ? true
2186                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2187        mBatteryStatsService.getActiveStatistics().setCallback(this);
2188
2189        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2190
2191        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2192
2193        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2194
2195        // User 0 is the first and only user that runs at boot.
2196        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2197        mUserLru.add(Integer.valueOf(0));
2198        updateStartedUserArrayLocked();
2199
2200        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2201            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2202
2203        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2204
2205        mConfiguration.setToDefaults();
2206        mConfiguration.locale = Locale.getDefault();
2207
2208        mConfigurationSeq = mConfiguration.seq = 1;
2209        mProcessCpuTracker.init();
2210
2211        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2212        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2213        mRecentTasks = new RecentTasks(this);
2214        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2215        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2216
2217        mProcessCpuThread = new Thread("CpuTracker") {
2218            @Override
2219            public void run() {
2220                while (true) {
2221                    try {
2222                        try {
2223                            synchronized(this) {
2224                                final long now = SystemClock.uptimeMillis();
2225                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2226                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2227                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2228                                //        + ", write delay=" + nextWriteDelay);
2229                                if (nextWriteDelay < nextCpuDelay) {
2230                                    nextCpuDelay = nextWriteDelay;
2231                                }
2232                                if (nextCpuDelay > 0) {
2233                                    mProcessCpuMutexFree.set(true);
2234                                    this.wait(nextCpuDelay);
2235                                }
2236                            }
2237                        } catch (InterruptedException e) {
2238                        }
2239                        updateCpuStatsNow();
2240                    } catch (Exception e) {
2241                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2242                    }
2243                }
2244            }
2245        };
2246
2247        Watchdog.getInstance().addMonitor(this);
2248        Watchdog.getInstance().addThread(mHandler);
2249    }
2250
2251    public void setSystemServiceManager(SystemServiceManager mgr) {
2252        mSystemServiceManager = mgr;
2253    }
2254
2255    public void setInstaller(Installer installer) {
2256        mInstaller = installer;
2257    }
2258
2259    private void start() {
2260        Process.removeAllProcessGroups();
2261        mProcessCpuThread.start();
2262
2263        mBatteryStatsService.publish(mContext);
2264        mAppOpsService.publish(mContext);
2265        Slog.d("AppOps", "AppOpsService published");
2266        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2267    }
2268
2269    public void initPowerManagement() {
2270        mStackSupervisor.initPowerManagement();
2271        mBatteryStatsService.initPowerManagement();
2272    }
2273
2274    @Override
2275    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2276            throws RemoteException {
2277        if (code == SYSPROPS_TRANSACTION) {
2278            // We need to tell all apps about the system property change.
2279            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2280            synchronized(this) {
2281                final int NP = mProcessNames.getMap().size();
2282                for (int ip=0; ip<NP; ip++) {
2283                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2284                    final int NA = apps.size();
2285                    for (int ia=0; ia<NA; ia++) {
2286                        ProcessRecord app = apps.valueAt(ia);
2287                        if (app.thread != null) {
2288                            procs.add(app.thread.asBinder());
2289                        }
2290                    }
2291                }
2292            }
2293
2294            int N = procs.size();
2295            for (int i=0; i<N; i++) {
2296                Parcel data2 = Parcel.obtain();
2297                try {
2298                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2299                } catch (RemoteException e) {
2300                }
2301                data2.recycle();
2302            }
2303        }
2304        try {
2305            return super.onTransact(code, data, reply, flags);
2306        } catch (RuntimeException e) {
2307            // The activity manager only throws security exceptions, so let's
2308            // log all others.
2309            if (!(e instanceof SecurityException)) {
2310                Slog.wtf(TAG, "Activity Manager Crash", e);
2311            }
2312            throw e;
2313        }
2314    }
2315
2316    void updateCpuStats() {
2317        final long now = SystemClock.uptimeMillis();
2318        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2319            return;
2320        }
2321        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2322            synchronized (mProcessCpuThread) {
2323                mProcessCpuThread.notify();
2324            }
2325        }
2326    }
2327
2328    void updateCpuStatsNow() {
2329        synchronized (mProcessCpuTracker) {
2330            mProcessCpuMutexFree.set(false);
2331            final long now = SystemClock.uptimeMillis();
2332            boolean haveNewCpuStats = false;
2333
2334            if (MONITOR_CPU_USAGE &&
2335                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2336                mLastCpuTime.set(now);
2337                mProcessCpuTracker.update();
2338                if (mProcessCpuTracker.hasGoodLastStats()) {
2339                    haveNewCpuStats = true;
2340                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2341                    //Slog.i(TAG, "Total CPU usage: "
2342                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2343
2344                    // Slog the cpu usage if the property is set.
2345                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2346                        int user = mProcessCpuTracker.getLastUserTime();
2347                        int system = mProcessCpuTracker.getLastSystemTime();
2348                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2349                        int irq = mProcessCpuTracker.getLastIrqTime();
2350                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2351                        int idle = mProcessCpuTracker.getLastIdleTime();
2352
2353                        int total = user + system + iowait + irq + softIrq + idle;
2354                        if (total == 0) total = 1;
2355
2356                        EventLog.writeEvent(EventLogTags.CPU,
2357                                ((user+system+iowait+irq+softIrq) * 100) / total,
2358                                (user * 100) / total,
2359                                (system * 100) / total,
2360                                (iowait * 100) / total,
2361                                (irq * 100) / total,
2362                                (softIrq * 100) / total);
2363                    }
2364                }
2365            }
2366
2367            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2368            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2369            synchronized(bstats) {
2370                synchronized(mPidsSelfLocked) {
2371                    if (haveNewCpuStats) {
2372                        final int perc = bstats.startAddingCpuLocked();
2373                        if (perc >= 0) {
2374                            int remainUTime = 0;
2375                            int remainSTime = 0;
2376                            int totalUTime = 0;
2377                            int totalSTime = 0;
2378                            final int N = mProcessCpuTracker.countStats();
2379                            for (int i=0; i<N; i++) {
2380                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2381                                if (!st.working) {
2382                                    continue;
2383                                }
2384                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2385                                int otherUTime = (st.rel_utime*perc)/100;
2386                                int otherSTime = (st.rel_stime*perc)/100;
2387                                remainUTime += otherUTime;
2388                                remainSTime += otherSTime;
2389                                totalUTime += st.rel_utime;
2390                                totalSTime += st.rel_stime;
2391                                if (pr != null) {
2392                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2393                                    if (ps == null || !ps.isActive()) {
2394                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2395                                                pr.info.uid, pr.processName);
2396                                    }
2397                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2398                                            st.rel_stime - otherSTime, cpuSpeedTimes);
2399                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2400                                } else {
2401                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2402                                    if (ps == null || !ps.isActive()) {
2403                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2404                                                bstats.mapUid(st.uid), st.name);
2405                                    }
2406                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2407                                            st.rel_stime - otherSTime, cpuSpeedTimes);
2408                                }
2409                            }
2410                            final int userTime = mProcessCpuTracker.getLastUserTime();
2411                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2412                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2413                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2414                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2415                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2416                            bstats.finishAddingCpuLocked(perc, remainUTime,
2417                                    remainSTime, totalUTime, totalSTime, userTime, systemTime,
2418                                    iowaitTime, irqTime, softIrqTime, idleTime, cpuSpeedTimes);
2419                        }
2420                    }
2421                }
2422
2423                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2424                    mLastWriteTime = now;
2425                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2426                }
2427            }
2428        }
2429    }
2430
2431    @Override
2432    public void batteryNeedsCpuUpdate() {
2433        updateCpuStatsNow();
2434    }
2435
2436    @Override
2437    public void batteryPowerChanged(boolean onBattery) {
2438        // When plugging in, update the CPU stats first before changing
2439        // the plug state.
2440        updateCpuStatsNow();
2441        synchronized (this) {
2442            synchronized(mPidsSelfLocked) {
2443                mOnBattery = DEBUG_POWER ? true : onBattery;
2444            }
2445        }
2446    }
2447
2448    /**
2449     * Initialize the application bind args. These are passed to each
2450     * process when the bindApplication() IPC is sent to the process. They're
2451     * lazily setup to make sure the services are running when they're asked for.
2452     */
2453    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2454        if (mAppBindArgs == null) {
2455            mAppBindArgs = new HashMap<>();
2456
2457            // Isolated processes won't get this optimization, so that we don't
2458            // violate the rules about which services they have access to.
2459            if (!isolated) {
2460                // Setup the application init args
2461                mAppBindArgs.put("package", ServiceManager.getService("package"));
2462                mAppBindArgs.put("window", ServiceManager.getService("window"));
2463                mAppBindArgs.put(Context.ALARM_SERVICE,
2464                        ServiceManager.getService(Context.ALARM_SERVICE));
2465            }
2466        }
2467        return mAppBindArgs;
2468    }
2469
2470    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2471        if (r != null && mFocusedActivity != r) {
2472            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2473            mFocusedActivity = r;
2474            if (r.task != null && r.task.voiceInteractor != null) {
2475                startRunningVoiceLocked();
2476            } else {
2477                finishRunningVoiceLocked();
2478            }
2479            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2480                mWindowManager.setFocusedApp(r.appToken, true);
2481            }
2482            applyUpdateLockStateLocked(r);
2483        }
2484        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
2485                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2486    }
2487
2488    final void clearFocusedActivity(ActivityRecord r) {
2489        if (mFocusedActivity == r) {
2490            mFocusedActivity = null;
2491        }
2492    }
2493
2494    @Override
2495    public void setFocusedStack(int stackId) {
2496        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2497        synchronized (ActivityManagerService.this) {
2498            ActivityStack stack = mStackSupervisor.getStack(stackId);
2499            if (stack != null) {
2500                ActivityRecord r = stack.topRunningActivityLocked(null);
2501                if (r != null) {
2502                    setFocusedActivityLocked(r, "setFocusedStack");
2503                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2504                }
2505            }
2506        }
2507    }
2508
2509    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2510    @Override
2511    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2512        synchronized (ActivityManagerService.this) {
2513            if (listener != null) {
2514                mTaskStackListeners.register(listener);
2515            }
2516        }
2517    }
2518
2519    @Override
2520    public void notifyActivityDrawn(IBinder token) {
2521        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2522        synchronized (this) {
2523            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2524            if (r != null) {
2525                r.task.stack.notifyActivityDrawnLocked(r);
2526            }
2527        }
2528    }
2529
2530    final void applyUpdateLockStateLocked(ActivityRecord r) {
2531        // Modifications to the UpdateLock state are done on our handler, outside
2532        // the activity manager's locks.  The new state is determined based on the
2533        // state *now* of the relevant activity record.  The object is passed to
2534        // the handler solely for logging detail, not to be consulted/modified.
2535        final boolean nextState = r != null && r.immersive;
2536        mHandler.sendMessage(
2537                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2538    }
2539
2540    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2541        Message msg = Message.obtain();
2542        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2543        msg.obj = r.task.askedCompatMode ? null : r;
2544        mHandler.sendMessage(msg);
2545    }
2546
2547    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2548            String what, Object obj, ProcessRecord srcApp) {
2549        app.lastActivityTime = now;
2550
2551        if (app.activities.size() > 0) {
2552            // Don't want to touch dependent processes that are hosting activities.
2553            return index;
2554        }
2555
2556        int lrui = mLruProcesses.lastIndexOf(app);
2557        if (lrui < 0) {
2558            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2559                    + what + " " + obj + " from " + srcApp);
2560            return index;
2561        }
2562
2563        if (lrui >= index) {
2564            // Don't want to cause this to move dependent processes *back* in the
2565            // list as if they were less frequently used.
2566            return index;
2567        }
2568
2569        if (lrui >= mLruProcessActivityStart) {
2570            // Don't want to touch dependent processes that are hosting activities.
2571            return index;
2572        }
2573
2574        mLruProcesses.remove(lrui);
2575        if (index > 0) {
2576            index--;
2577        }
2578        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2579                + " in LRU list: " + app);
2580        mLruProcesses.add(index, app);
2581        return index;
2582    }
2583
2584    final void removeLruProcessLocked(ProcessRecord app) {
2585        int lrui = mLruProcesses.lastIndexOf(app);
2586        if (lrui >= 0) {
2587            if (!app.killed) {
2588                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2589                Process.killProcessQuiet(app.pid);
2590                Process.killProcessGroup(app.info.uid, app.pid);
2591            }
2592            if (lrui <= mLruProcessActivityStart) {
2593                mLruProcessActivityStart--;
2594            }
2595            if (lrui <= mLruProcessServiceStart) {
2596                mLruProcessServiceStart--;
2597            }
2598            mLruProcesses.remove(lrui);
2599        }
2600    }
2601
2602    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2603            ProcessRecord client) {
2604        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2605                || app.treatLikeActivity;
2606        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2607        if (!activityChange && hasActivity) {
2608            // The process has activities, so we are only allowing activity-based adjustments
2609            // to move it.  It should be kept in the front of the list with other
2610            // processes that have activities, and we don't want those to change their
2611            // order except due to activity operations.
2612            return;
2613        }
2614
2615        mLruSeq++;
2616        final long now = SystemClock.uptimeMillis();
2617        app.lastActivityTime = now;
2618
2619        // First a quick reject: if the app is already at the position we will
2620        // put it, then there is nothing to do.
2621        if (hasActivity) {
2622            final int N = mLruProcesses.size();
2623            if (N > 0 && mLruProcesses.get(N-1) == app) {
2624                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2625                return;
2626            }
2627        } else {
2628            if (mLruProcessServiceStart > 0
2629                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2630                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2631                return;
2632            }
2633        }
2634
2635        int lrui = mLruProcesses.lastIndexOf(app);
2636
2637        if (app.persistent && lrui >= 0) {
2638            // We don't care about the position of persistent processes, as long as
2639            // they are in the list.
2640            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2641            return;
2642        }
2643
2644        /* In progress: compute new position first, so we can avoid doing work
2645           if the process is not actually going to move.  Not yet working.
2646        int addIndex;
2647        int nextIndex;
2648        boolean inActivity = false, inService = false;
2649        if (hasActivity) {
2650            // Process has activities, put it at the very tipsy-top.
2651            addIndex = mLruProcesses.size();
2652            nextIndex = mLruProcessServiceStart;
2653            inActivity = true;
2654        } else if (hasService) {
2655            // Process has services, put it at the top of the service list.
2656            addIndex = mLruProcessActivityStart;
2657            nextIndex = mLruProcessServiceStart;
2658            inActivity = true;
2659            inService = true;
2660        } else  {
2661            // Process not otherwise of interest, it goes to the top of the non-service area.
2662            addIndex = mLruProcessServiceStart;
2663            if (client != null) {
2664                int clientIndex = mLruProcesses.lastIndexOf(client);
2665                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2666                        + app);
2667                if (clientIndex >= 0 && addIndex > clientIndex) {
2668                    addIndex = clientIndex;
2669                }
2670            }
2671            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2672        }
2673
2674        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2675                + mLruProcessActivityStart + "): " + app);
2676        */
2677
2678        if (lrui >= 0) {
2679            if (lrui < mLruProcessActivityStart) {
2680                mLruProcessActivityStart--;
2681            }
2682            if (lrui < mLruProcessServiceStart) {
2683                mLruProcessServiceStart--;
2684            }
2685            /*
2686            if (addIndex > lrui) {
2687                addIndex--;
2688            }
2689            if (nextIndex > lrui) {
2690                nextIndex--;
2691            }
2692            */
2693            mLruProcesses.remove(lrui);
2694        }
2695
2696        /*
2697        mLruProcesses.add(addIndex, app);
2698        if (inActivity) {
2699            mLruProcessActivityStart++;
2700        }
2701        if (inService) {
2702            mLruProcessActivityStart++;
2703        }
2704        */
2705
2706        int nextIndex;
2707        if (hasActivity) {
2708            final int N = mLruProcesses.size();
2709            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2710                // Process doesn't have activities, but has clients with
2711                // activities...  move it up, but one below the top (the top
2712                // should always have a real activity).
2713                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2714                mLruProcesses.add(N-1, app);
2715                // To keep it from spamming the LRU list (by making a bunch of clients),
2716                // we will push down any other entries owned by the app.
2717                final int uid = app.info.uid;
2718                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2719                    ProcessRecord subProc = mLruProcesses.get(i);
2720                    if (subProc.info.uid == uid) {
2721                        // We want to push this one down the list.  If the process after
2722                        // it is for the same uid, however, don't do so, because we don't
2723                        // want them internally to be re-ordered.
2724                        if (mLruProcesses.get(i-1).info.uid != uid) {
2725                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2726                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2727                            ProcessRecord tmp = mLruProcesses.get(i);
2728                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2729                            mLruProcesses.set(i-1, tmp);
2730                            i--;
2731                        }
2732                    } else {
2733                        // A gap, we can stop here.
2734                        break;
2735                    }
2736                }
2737            } else {
2738                // Process has activities, put it at the very tipsy-top.
2739                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2740                mLruProcesses.add(app);
2741            }
2742            nextIndex = mLruProcessServiceStart;
2743        } else if (hasService) {
2744            // Process has services, put it at the top of the service list.
2745            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2746            mLruProcesses.add(mLruProcessActivityStart, app);
2747            nextIndex = mLruProcessServiceStart;
2748            mLruProcessActivityStart++;
2749        } else  {
2750            // Process not otherwise of interest, it goes to the top of the non-service area.
2751            int index = mLruProcessServiceStart;
2752            if (client != null) {
2753                // If there is a client, don't allow the process to be moved up higher
2754                // in the list than that client.
2755                int clientIndex = mLruProcesses.lastIndexOf(client);
2756                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2757                        + " when updating " + app);
2758                if (clientIndex <= lrui) {
2759                    // Don't allow the client index restriction to push it down farther in the
2760                    // list than it already is.
2761                    clientIndex = lrui;
2762                }
2763                if (clientIndex >= 0 && index > clientIndex) {
2764                    index = clientIndex;
2765                }
2766            }
2767            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2768            mLruProcesses.add(index, app);
2769            nextIndex = index-1;
2770            mLruProcessActivityStart++;
2771            mLruProcessServiceStart++;
2772        }
2773
2774        // If the app is currently using a content provider or service,
2775        // bump those processes as well.
2776        for (int j=app.connections.size()-1; j>=0; j--) {
2777            ConnectionRecord cr = app.connections.valueAt(j);
2778            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2779                    && cr.binding.service.app != null
2780                    && cr.binding.service.app.lruSeq != mLruSeq
2781                    && !cr.binding.service.app.persistent) {
2782                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2783                        "service connection", cr, app);
2784            }
2785        }
2786        for (int j=app.conProviders.size()-1; j>=0; j--) {
2787            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2788            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2789                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2790                        "provider reference", cpr, app);
2791            }
2792        }
2793    }
2794
2795    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2796        if (uid == Process.SYSTEM_UID) {
2797            // The system gets to run in any process.  If there are multiple
2798            // processes with the same uid, just pick the first (this
2799            // should never happen).
2800            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2801            if (procs == null) return null;
2802            final int N = procs.size();
2803            for (int i = 0; i < N; i++) {
2804                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2805            }
2806        }
2807        ProcessRecord proc = mProcessNames.get(processName, uid);
2808        if (false && proc != null && !keepIfLarge
2809                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2810                && proc.lastCachedPss >= 4000) {
2811            // Turn this condition on to cause killing to happen regularly, for testing.
2812            if (proc.baseProcessTracker != null) {
2813                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2814            }
2815            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2816        } else if (proc != null && !keepIfLarge
2817                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2818                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2819            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2820            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2821                if (proc.baseProcessTracker != null) {
2822                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2823                }
2824                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2825            }
2826        }
2827        return proc;
2828    }
2829
2830    void ensurePackageDexOpt(String packageName) {
2831        IPackageManager pm = AppGlobals.getPackageManager();
2832        try {
2833            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2834                mDidDexOpt = true;
2835            }
2836        } catch (RemoteException e) {
2837        }
2838    }
2839
2840    boolean isNextTransitionForward() {
2841        int transit = mWindowManager.getPendingAppTransition();
2842        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2843                || transit == AppTransition.TRANSIT_TASK_OPEN
2844                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2845    }
2846
2847    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2848            String processName, String abiOverride, int uid, Runnable crashHandler) {
2849        synchronized(this) {
2850            ApplicationInfo info = new ApplicationInfo();
2851            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2852            // For isolated processes, the former contains the parent's uid and the latter the
2853            // actual uid of the isolated process.
2854            // In the special case introduced by this method (which is, starting an isolated
2855            // process directly from the SystemServer without an actual parent app process) the
2856            // closest thing to a parent's uid is SYSTEM_UID.
2857            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2858            // the |isolated| logic in the ProcessRecord constructor.
2859            info.uid = Process.SYSTEM_UID;
2860            info.processName = processName;
2861            info.className = entryPoint;
2862            info.packageName = "android";
2863            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2864                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2865                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2866                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2867                    crashHandler);
2868            return proc != null ? proc.pid : 0;
2869        }
2870    }
2871
2872    final ProcessRecord startProcessLocked(String processName,
2873            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2874            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2875            boolean isolated, boolean keepIfLarge) {
2876        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2877                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2878                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2879                null /* crashHandler */);
2880    }
2881
2882    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2883            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2884            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2885            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2886        long startTime = SystemClock.elapsedRealtime();
2887        ProcessRecord app;
2888        if (!isolated) {
2889            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2890            checkTime(startTime, "startProcess: after getProcessRecord");
2891        } else {
2892            // If this is an isolated process, it can't re-use an existing process.
2893            app = null;
2894        }
2895        // We don't have to do anything more if:
2896        // (1) There is an existing application record; and
2897        // (2) The caller doesn't think it is dead, OR there is no thread
2898        //     object attached to it so we know it couldn't have crashed; and
2899        // (3) There is a pid assigned to it, so it is either starting or
2900        //     already running.
2901        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2902                + " app=" + app + " knownToBeDead=" + knownToBeDead
2903                + " thread=" + (app != null ? app.thread : null)
2904                + " pid=" + (app != null ? app.pid : -1));
2905        if (app != null && app.pid > 0) {
2906            if (!knownToBeDead || app.thread == null) {
2907                // We already have the app running, or are waiting for it to
2908                // come up (we have a pid but not yet its thread), so keep it.
2909                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2910                // If this is a new package in the process, add the package to the list
2911                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2912                checkTime(startTime, "startProcess: done, added package to proc");
2913                return app;
2914            }
2915
2916            // An application record is attached to a previous process,
2917            // clean it up now.
2918            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2919            checkTime(startTime, "startProcess: bad proc running, killing");
2920            Process.killProcessGroup(app.info.uid, app.pid);
2921            handleAppDiedLocked(app, true, true);
2922            checkTime(startTime, "startProcess: done killing old proc");
2923        }
2924
2925        String hostingNameStr = hostingName != null
2926                ? hostingName.flattenToShortString() : null;
2927
2928        if (!isolated) {
2929            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2930                // If we are in the background, then check to see if this process
2931                // is bad.  If so, we will just silently fail.
2932                if (mBadProcesses.get(info.processName, info.uid) != null) {
2933                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2934                            + "/" + info.processName);
2935                    return null;
2936                }
2937            } else {
2938                // When the user is explicitly starting a process, then clear its
2939                // crash count so that we won't make it bad until they see at
2940                // least one crash dialog again, and make the process good again
2941                // if it had been bad.
2942                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2943                        + "/" + info.processName);
2944                mProcessCrashTimes.remove(info.processName, info.uid);
2945                if (mBadProcesses.get(info.processName, info.uid) != null) {
2946                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2947                            UserHandle.getUserId(info.uid), info.uid,
2948                            info.processName);
2949                    mBadProcesses.remove(info.processName, info.uid);
2950                    if (app != null) {
2951                        app.bad = false;
2952                    }
2953                }
2954            }
2955        }
2956
2957        if (app == null) {
2958            checkTime(startTime, "startProcess: creating new process record");
2959            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2960            if (app == null) {
2961                Slog.w(TAG, "Failed making new process record for "
2962                        + processName + "/" + info.uid + " isolated=" + isolated);
2963                return null;
2964            }
2965            app.crashHandler = crashHandler;
2966            mProcessNames.put(processName, app.uid, app);
2967            if (isolated) {
2968                mIsolatedProcesses.put(app.uid, app);
2969            }
2970            checkTime(startTime, "startProcess: done creating new process record");
2971        } else {
2972            // If this is a new package in the process, add the package to the list
2973            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2974            checkTime(startTime, "startProcess: added package to existing proc");
2975        }
2976
2977        // If the system is not ready yet, then hold off on starting this
2978        // process until it is.
2979        if (!mProcessesReady
2980                && !isAllowedWhileBooting(info)
2981                && !allowWhileBooting) {
2982            if (!mProcessesOnHold.contains(app)) {
2983                mProcessesOnHold.add(app);
2984            }
2985            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2986            checkTime(startTime, "startProcess: returning with proc on hold");
2987            return app;
2988        }
2989
2990        checkTime(startTime, "startProcess: stepping in to startProcess");
2991        startProcessLocked(
2992                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2993        checkTime(startTime, "startProcess: done starting proc!");
2994        return (app.pid != 0) ? app : null;
2995    }
2996
2997    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2998        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2999    }
3000
3001    private final void startProcessLocked(ProcessRecord app,
3002            String hostingType, String hostingNameStr) {
3003        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3004                null /* entryPoint */, null /* entryPointArgs */);
3005    }
3006
3007    private final void startProcessLocked(ProcessRecord app, String hostingType,
3008            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3009        long startTime = SystemClock.elapsedRealtime();
3010        if (app.pid > 0 && app.pid != MY_PID) {
3011            checkTime(startTime, "startProcess: removing from pids map");
3012            synchronized (mPidsSelfLocked) {
3013                mPidsSelfLocked.remove(app.pid);
3014                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3015            }
3016            checkTime(startTime, "startProcess: done removing from pids map");
3017            app.setPid(0);
3018        }
3019
3020        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3021                "startProcessLocked removing on hold: " + app);
3022        mProcessesOnHold.remove(app);
3023
3024        checkTime(startTime, "startProcess: starting to update cpu stats");
3025        updateCpuStats();
3026        checkTime(startTime, "startProcess: done updating cpu stats");
3027
3028        try {
3029            int uid = app.uid;
3030
3031            int[] gids = null;
3032            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3033            if (!app.isolated) {
3034                int[] permGids = null;
3035                try {
3036                    checkTime(startTime, "startProcess: getting gids from package manager");
3037                    final PackageManager pm = mContext.getPackageManager();
3038                    permGids = pm.getPackageGids(app.info.packageName);
3039
3040                    if (Environment.isExternalStorageEmulated()) {
3041                        checkTime(startTime, "startProcess: checking external storage perm");
3042                        if (pm.checkPermission(
3043                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3044                                app.info.packageName) == PERMISSION_GRANTED) {
3045                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3046                        } else {
3047                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3048                        }
3049                    }
3050                } catch (PackageManager.NameNotFoundException e) {
3051                    Slog.w(TAG, "Unable to retrieve gids", e);
3052                }
3053
3054                /*
3055                 * Add shared application and profile GIDs so applications can share some
3056                 * resources like shared libraries and access user-wide resources
3057                 */
3058                if (permGids == null) {
3059                    gids = new int[2];
3060                } else {
3061                    gids = new int[permGids.length + 2];
3062                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3063                }
3064                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3065                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3066            }
3067            checkTime(startTime, "startProcess: building args");
3068            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3069                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3070                        && mTopComponent != null
3071                        && app.processName.equals(mTopComponent.getPackageName())) {
3072                    uid = 0;
3073                }
3074                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3075                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3076                    uid = 0;
3077                }
3078            }
3079            int debugFlags = 0;
3080            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3081                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3082                // Also turn on CheckJNI for debuggable apps. It's quite
3083                // awkward to turn on otherwise.
3084                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3085            }
3086            // Run the app in safe mode if its manifest requests so or the
3087            // system is booted in safe mode.
3088            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3089                mSafeMode == true) {
3090                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3091            }
3092            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3093                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3094            }
3095            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3096                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3097            }
3098            if ("1".equals(SystemProperties.get("debug.assert"))) {
3099                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3100            }
3101
3102            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3103            if (requiredAbi == null) {
3104                requiredAbi = Build.SUPPORTED_ABIS[0];
3105            }
3106
3107            String instructionSet = null;
3108            if (app.info.primaryCpuAbi != null) {
3109                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3110            }
3111
3112            app.gids = gids;
3113            app.requiredAbi = requiredAbi;
3114            app.instructionSet = instructionSet;
3115
3116            // Start the process.  It will either succeed and return a result containing
3117            // the PID of the new process, or else throw a RuntimeException.
3118            boolean isActivityProcess = (entryPoint == null);
3119            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3120            checkTime(startTime, "startProcess: asking zygote to start proc");
3121            Process.ProcessStartResult startResult = Process.start(entryPoint,
3122                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3123                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3124                    app.info.dataDir, entryPointArgs);
3125            checkTime(startTime, "startProcess: returned from zygote!");
3126
3127            if (app.isolated) {
3128                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3129            }
3130            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3131            checkTime(startTime, "startProcess: done updating battery stats");
3132
3133            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3134                    UserHandle.getUserId(uid), startResult.pid, uid,
3135                    app.processName, hostingType,
3136                    hostingNameStr != null ? hostingNameStr : "");
3137
3138            if (app.persistent) {
3139                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3140            }
3141
3142            checkTime(startTime, "startProcess: building log message");
3143            StringBuilder buf = mStringBuilder;
3144            buf.setLength(0);
3145            buf.append("Start proc ");
3146            buf.append(startResult.pid);
3147            buf.append(':');
3148            buf.append(app.processName);
3149            buf.append('/');
3150            UserHandle.formatUid(buf, uid);
3151            if (!isActivityProcess) {
3152                buf.append(" [");
3153                buf.append(entryPoint);
3154                buf.append("]");
3155            }
3156            buf.append(" for ");
3157            buf.append(hostingType);
3158            if (hostingNameStr != null) {
3159                buf.append(" ");
3160                buf.append(hostingNameStr);
3161            }
3162            Slog.i(TAG, buf.toString());
3163            app.setPid(startResult.pid);
3164            app.usingWrapper = startResult.usingWrapper;
3165            app.removed = false;
3166            app.killed = false;
3167            app.killedByAm = false;
3168            checkTime(startTime, "startProcess: starting to update pids map");
3169            synchronized (mPidsSelfLocked) {
3170                this.mPidsSelfLocked.put(startResult.pid, app);
3171                if (isActivityProcess) {
3172                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3173                    msg.obj = app;
3174                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3175                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3176                }
3177            }
3178            checkTime(startTime, "startProcess: done updating pids map");
3179        } catch (RuntimeException e) {
3180            // XXX do better error recovery.
3181            app.setPid(0);
3182            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3183            if (app.isolated) {
3184                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3185            }
3186            Slog.e(TAG, "Failure starting process " + app.processName, e);
3187        }
3188    }
3189
3190    void updateUsageStats(ActivityRecord component, boolean resumed) {
3191        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3192        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3193        if (resumed) {
3194            if (mUsageStatsService != null) {
3195                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3196                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3197            }
3198            synchronized (stats) {
3199                stats.noteActivityResumedLocked(component.app.uid);
3200            }
3201        } else {
3202            if (mUsageStatsService != null) {
3203                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3204                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3205            }
3206            synchronized (stats) {
3207                stats.noteActivityPausedLocked(component.app.uid);
3208            }
3209        }
3210    }
3211
3212    Intent getHomeIntent() {
3213        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3214        intent.setComponent(mTopComponent);
3215        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3216            intent.addCategory(Intent.CATEGORY_HOME);
3217        }
3218        return intent;
3219    }
3220
3221    boolean startHomeActivityLocked(int userId, String reason) {
3222        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3223                && mTopAction == null) {
3224            // We are running in factory test mode, but unable to find
3225            // the factory test app, so just sit around displaying the
3226            // error message and don't try to start anything.
3227            return false;
3228        }
3229        Intent intent = getHomeIntent();
3230        ActivityInfo aInfo =
3231            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3232        if (aInfo != null) {
3233            intent.setComponent(new ComponentName(
3234                    aInfo.applicationInfo.packageName, aInfo.name));
3235            // Don't do this if the home app is currently being
3236            // instrumented.
3237            aInfo = new ActivityInfo(aInfo);
3238            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3239            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3240                    aInfo.applicationInfo.uid, true);
3241            if (app == null || app.instrumentationClass == null) {
3242                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3243                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3244            }
3245        }
3246
3247        return true;
3248    }
3249
3250    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3251        ActivityInfo ai = null;
3252        ComponentName comp = intent.getComponent();
3253        try {
3254            if (comp != null) {
3255                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3256            } else {
3257                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3258                        intent,
3259                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3260                            flags, userId);
3261
3262                if (info != null) {
3263                    ai = info.activityInfo;
3264                }
3265            }
3266        } catch (RemoteException e) {
3267            // ignore
3268        }
3269
3270        return ai;
3271    }
3272
3273    /**
3274     * Starts the "new version setup screen" if appropriate.
3275     */
3276    void startSetupActivityLocked() {
3277        // Only do this once per boot.
3278        if (mCheckedForSetup) {
3279            return;
3280        }
3281
3282        // We will show this screen if the current one is a different
3283        // version than the last one shown, and we are not running in
3284        // low-level factory test mode.
3285        final ContentResolver resolver = mContext.getContentResolver();
3286        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3287                Settings.Global.getInt(resolver,
3288                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3289            mCheckedForSetup = true;
3290
3291            // See if we should be showing the platform update setup UI.
3292            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3293            List<ResolveInfo> ris = mContext.getPackageManager()
3294                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3295
3296            // We don't allow third party apps to replace this.
3297            ResolveInfo ri = null;
3298            for (int i=0; ris != null && i<ris.size(); i++) {
3299                if ((ris.get(i).activityInfo.applicationInfo.flags
3300                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3301                    ri = ris.get(i);
3302                    break;
3303                }
3304            }
3305
3306            if (ri != null) {
3307                String vers = ri.activityInfo.metaData != null
3308                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3309                        : null;
3310                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3311                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3312                            Intent.METADATA_SETUP_VERSION);
3313                }
3314                String lastVers = Settings.Secure.getString(
3315                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3316                if (vers != null && !vers.equals(lastVers)) {
3317                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3318                    intent.setComponent(new ComponentName(
3319                            ri.activityInfo.packageName, ri.activityInfo.name));
3320                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3321                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3322                            null);
3323                }
3324            }
3325        }
3326    }
3327
3328    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3329        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3330    }
3331
3332    void enforceNotIsolatedCaller(String caller) {
3333        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3334            throw new SecurityException("Isolated process not allowed to call " + caller);
3335        }
3336    }
3337
3338    void enforceShellRestriction(String restriction, int userHandle) {
3339        if (Binder.getCallingUid() == Process.SHELL_UID) {
3340            if (userHandle < 0
3341                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3342                throw new SecurityException("Shell does not have permission to access user "
3343                        + userHandle);
3344            }
3345        }
3346    }
3347
3348    @Override
3349    public int getFrontActivityScreenCompatMode() {
3350        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3351        synchronized (this) {
3352            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3353        }
3354    }
3355
3356    @Override
3357    public void setFrontActivityScreenCompatMode(int mode) {
3358        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3359                "setFrontActivityScreenCompatMode");
3360        synchronized (this) {
3361            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3362        }
3363    }
3364
3365    @Override
3366    public int getPackageScreenCompatMode(String packageName) {
3367        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3368        synchronized (this) {
3369            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3370        }
3371    }
3372
3373    @Override
3374    public void setPackageScreenCompatMode(String packageName, int mode) {
3375        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3376                "setPackageScreenCompatMode");
3377        synchronized (this) {
3378            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3379        }
3380    }
3381
3382    @Override
3383    public boolean getPackageAskScreenCompat(String packageName) {
3384        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3385        synchronized (this) {
3386            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3387        }
3388    }
3389
3390    @Override
3391    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3392        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3393                "setPackageAskScreenCompat");
3394        synchronized (this) {
3395            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3396        }
3397    }
3398
3399    private void dispatchProcessesChanged() {
3400        int N;
3401        synchronized (this) {
3402            N = mPendingProcessChanges.size();
3403            if (mActiveProcessChanges.length < N) {
3404                mActiveProcessChanges = new ProcessChangeItem[N];
3405            }
3406            mPendingProcessChanges.toArray(mActiveProcessChanges);
3407            mAvailProcessChanges.addAll(mPendingProcessChanges);
3408            mPendingProcessChanges.clear();
3409            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3410        }
3411
3412        int i = mProcessObservers.beginBroadcast();
3413        while (i > 0) {
3414            i--;
3415            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3416            if (observer != null) {
3417                try {
3418                    for (int j=0; j<N; j++) {
3419                        ProcessChangeItem item = mActiveProcessChanges[j];
3420                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3421                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3422                                    + item.pid + " uid=" + item.uid + ": "
3423                                    + item.foregroundActivities);
3424                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3425                                    item.foregroundActivities);
3426                        }
3427                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3428                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3429                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3430                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3431                        }
3432                    }
3433                } catch (RemoteException e) {
3434                }
3435            }
3436        }
3437        mProcessObservers.finishBroadcast();
3438    }
3439
3440    private void dispatchProcessDied(int pid, int uid) {
3441        int i = mProcessObservers.beginBroadcast();
3442        while (i > 0) {
3443            i--;
3444            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3445            if (observer != null) {
3446                try {
3447                    observer.onProcessDied(pid, uid);
3448                } catch (RemoteException e) {
3449                }
3450            }
3451        }
3452        mProcessObservers.finishBroadcast();
3453    }
3454
3455    @Override
3456    public final int startActivity(IApplicationThread caller, String callingPackage,
3457            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3458            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3459        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3460            resultWho, requestCode, startFlags, profilerInfo, options,
3461            UserHandle.getCallingUserId());
3462    }
3463
3464    @Override
3465    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3466            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3467            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3468        enforceNotIsolatedCaller("startActivity");
3469        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3470                false, ALLOW_FULL_ONLY, "startActivity", null);
3471        // TODO: Switch to user app stacks here.
3472        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3473                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3474                profilerInfo, null, null, options, userId, null, null);
3475    }
3476
3477    @Override
3478    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3479            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3480            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3481
3482        // This is very dangerous -- it allows you to perform a start activity (including
3483        // permission grants) as any app that may launch one of your own activities.  So
3484        // we will only allow this to be done from activities that are part of the core framework,
3485        // and then only when they are running as the system.
3486        final ActivityRecord sourceRecord;
3487        final int targetUid;
3488        final String targetPackage;
3489        synchronized (this) {
3490            if (resultTo == null) {
3491                throw new SecurityException("Must be called from an activity");
3492            }
3493            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3494            if (sourceRecord == null) {
3495                throw new SecurityException("Called with bad activity token: " + resultTo);
3496            }
3497            if (!sourceRecord.info.packageName.equals("android")) {
3498                throw new SecurityException(
3499                        "Must be called from an activity that is declared in the android package");
3500            }
3501            if (sourceRecord.app == null) {
3502                throw new SecurityException("Called without a process attached to activity");
3503            }
3504            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3505                // This is still okay, as long as this activity is running under the
3506                // uid of the original calling activity.
3507                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3508                    throw new SecurityException(
3509                            "Calling activity in uid " + sourceRecord.app.uid
3510                                    + " must be system uid or original calling uid "
3511                                    + sourceRecord.launchedFromUid);
3512                }
3513            }
3514            targetUid = sourceRecord.launchedFromUid;
3515            targetPackage = sourceRecord.launchedFromPackage;
3516        }
3517
3518        if (userId == UserHandle.USER_NULL) {
3519            userId = UserHandle.getUserId(sourceRecord.app.uid);
3520        }
3521
3522        // TODO: Switch to user app stacks here.
3523        try {
3524            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3525                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3526                    null, null, options, userId, null, null);
3527            return ret;
3528        } catch (SecurityException e) {
3529            // XXX need to figure out how to propagate to original app.
3530            // A SecurityException here is generally actually a fault of the original
3531            // calling activity (such as a fairly granting permissions), so propagate it
3532            // back to them.
3533            /*
3534            StringBuilder msg = new StringBuilder();
3535            msg.append("While launching");
3536            msg.append(intent.toString());
3537            msg.append(": ");
3538            msg.append(e.getMessage());
3539            */
3540            throw e;
3541        }
3542    }
3543
3544    @Override
3545    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3546            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3547            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3548        enforceNotIsolatedCaller("startActivityAndWait");
3549        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3550                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3551        WaitResult res = new WaitResult();
3552        // TODO: Switch to user app stacks here.
3553        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3554                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3555                options, userId, null, null);
3556        return res;
3557    }
3558
3559    @Override
3560    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3561            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3562            int startFlags, Configuration config, Bundle options, int userId) {
3563        enforceNotIsolatedCaller("startActivityWithConfig");
3564        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3565                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3566        // TODO: Switch to user app stacks here.
3567        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3568                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3569                null, null, config, options, userId, null, null);
3570        return ret;
3571    }
3572
3573    @Override
3574    public int startActivityIntentSender(IApplicationThread caller,
3575            IntentSender intent, Intent fillInIntent, String resolvedType,
3576            IBinder resultTo, String resultWho, int requestCode,
3577            int flagsMask, int flagsValues, Bundle options) {
3578        enforceNotIsolatedCaller("startActivityIntentSender");
3579        // Refuse possible leaked file descriptors
3580        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3581            throw new IllegalArgumentException("File descriptors passed in Intent");
3582        }
3583
3584        IIntentSender sender = intent.getTarget();
3585        if (!(sender instanceof PendingIntentRecord)) {
3586            throw new IllegalArgumentException("Bad PendingIntent object");
3587        }
3588
3589        PendingIntentRecord pir = (PendingIntentRecord)sender;
3590
3591        synchronized (this) {
3592            // If this is coming from the currently resumed activity, it is
3593            // effectively saying that app switches are allowed at this point.
3594            final ActivityStack stack = getFocusedStack();
3595            if (stack.mResumedActivity != null &&
3596                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3597                mAppSwitchesAllowedTime = 0;
3598            }
3599        }
3600        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3601                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3602        return ret;
3603    }
3604
3605    @Override
3606    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3607            Intent intent, String resolvedType, IVoiceInteractionSession session,
3608            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3609            Bundle options, int userId) {
3610        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3611                != PackageManager.PERMISSION_GRANTED) {
3612            String msg = "Permission Denial: startVoiceActivity() from pid="
3613                    + Binder.getCallingPid()
3614                    + ", uid=" + Binder.getCallingUid()
3615                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3616            Slog.w(TAG, msg);
3617            throw new SecurityException(msg);
3618        }
3619        if (session == null || interactor == null) {
3620            throw new NullPointerException("null session or interactor");
3621        }
3622        userId = handleIncomingUser(callingPid, callingUid, userId,
3623                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3624        // TODO: Switch to user app stacks here.
3625        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3626                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3627                null, options, userId, null, null);
3628    }
3629
3630    @Override
3631    public boolean startNextMatchingActivity(IBinder callingActivity,
3632            Intent intent, Bundle options) {
3633        // Refuse possible leaked file descriptors
3634        if (intent != null && intent.hasFileDescriptors() == true) {
3635            throw new IllegalArgumentException("File descriptors passed in Intent");
3636        }
3637
3638        synchronized (this) {
3639            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3640            if (r == null) {
3641                ActivityOptions.abort(options);
3642                return false;
3643            }
3644            if (r.app == null || r.app.thread == null) {
3645                // The caller is not running...  d'oh!
3646                ActivityOptions.abort(options);
3647                return false;
3648            }
3649            intent = new Intent(intent);
3650            // The caller is not allowed to change the data.
3651            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3652            // And we are resetting to find the next component...
3653            intent.setComponent(null);
3654
3655            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3656
3657            ActivityInfo aInfo = null;
3658            try {
3659                List<ResolveInfo> resolves =
3660                    AppGlobals.getPackageManager().queryIntentActivities(
3661                            intent, r.resolvedType,
3662                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3663                            UserHandle.getCallingUserId());
3664
3665                // Look for the original activity in the list...
3666                final int N = resolves != null ? resolves.size() : 0;
3667                for (int i=0; i<N; i++) {
3668                    ResolveInfo rInfo = resolves.get(i);
3669                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3670                            && rInfo.activityInfo.name.equals(r.info.name)) {
3671                        // We found the current one...  the next matching is
3672                        // after it.
3673                        i++;
3674                        if (i<N) {
3675                            aInfo = resolves.get(i).activityInfo;
3676                        }
3677                        if (debug) {
3678                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3679                                    + "/" + r.info.name);
3680                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3681                                    + "/" + aInfo.name);
3682                        }
3683                        break;
3684                    }
3685                }
3686            } catch (RemoteException e) {
3687            }
3688
3689            if (aInfo == null) {
3690                // Nobody who is next!
3691                ActivityOptions.abort(options);
3692                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3693                return false;
3694            }
3695
3696            intent.setComponent(new ComponentName(
3697                    aInfo.applicationInfo.packageName, aInfo.name));
3698            intent.setFlags(intent.getFlags()&~(
3699                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3700                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3701                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3702                    Intent.FLAG_ACTIVITY_NEW_TASK));
3703
3704            // Okay now we need to start the new activity, replacing the
3705            // currently running activity.  This is a little tricky because
3706            // we want to start the new one as if the current one is finished,
3707            // but not finish the current one first so that there is no flicker.
3708            // And thus...
3709            final boolean wasFinishing = r.finishing;
3710            r.finishing = true;
3711
3712            // Propagate reply information over to the new activity.
3713            final ActivityRecord resultTo = r.resultTo;
3714            final String resultWho = r.resultWho;
3715            final int requestCode = r.requestCode;
3716            r.resultTo = null;
3717            if (resultTo != null) {
3718                resultTo.removeResultsLocked(r, resultWho, requestCode);
3719            }
3720
3721            final long origId = Binder.clearCallingIdentity();
3722            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3723                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3724                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3725                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3726            Binder.restoreCallingIdentity(origId);
3727
3728            r.finishing = wasFinishing;
3729            if (res != ActivityManager.START_SUCCESS) {
3730                return false;
3731            }
3732            return true;
3733        }
3734    }
3735
3736    @Override
3737    public final int startActivityFromRecents(int taskId, Bundle options) {
3738        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3739            String msg = "Permission Denial: startActivityFromRecents called without " +
3740                    START_TASKS_FROM_RECENTS;
3741            Slog.w(TAG, msg);
3742            throw new SecurityException(msg);
3743        }
3744        return startActivityFromRecentsInner(taskId, options);
3745    }
3746
3747    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3748        final TaskRecord task;
3749        final int callingUid;
3750        final String callingPackage;
3751        final Intent intent;
3752        final int userId;
3753        synchronized (this) {
3754            task = mRecentTasks.taskForIdLocked(taskId);
3755            if (task == null) {
3756                throw new IllegalArgumentException("Task " + taskId + " not found.");
3757            }
3758            if (task.getRootActivity() != null) {
3759                moveTaskToFrontLocked(task.taskId, 0, null);
3760                return ActivityManager.START_TASK_TO_FRONT;
3761            }
3762            callingUid = task.mCallingUid;
3763            callingPackage = task.mCallingPackage;
3764            intent = task.intent;
3765            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3766            userId = task.userId;
3767        }
3768        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3769                options, userId, null, task);
3770    }
3771
3772    final int startActivityInPackage(int uid, String callingPackage,
3773            Intent intent, String resolvedType, IBinder resultTo,
3774            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3775            IActivityContainer container, TaskRecord inTask) {
3776
3777        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3778                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3779
3780        // TODO: Switch to user app stacks here.
3781        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3782                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3783                null, null, null, options, userId, container, inTask);
3784        return ret;
3785    }
3786
3787    @Override
3788    public final int startActivities(IApplicationThread caller, String callingPackage,
3789            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3790            int userId) {
3791        enforceNotIsolatedCaller("startActivities");
3792        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3793                false, ALLOW_FULL_ONLY, "startActivity", null);
3794        // TODO: Switch to user app stacks here.
3795        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3796                resolvedTypes, resultTo, options, userId);
3797        return ret;
3798    }
3799
3800    final int startActivitiesInPackage(int uid, String callingPackage,
3801            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3802            Bundle options, int userId) {
3803
3804        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3805                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3806        // TODO: Switch to user app stacks here.
3807        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3808                resultTo, options, userId);
3809        return ret;
3810    }
3811
3812    @Override
3813    public void reportActivityFullyDrawn(IBinder token) {
3814        synchronized (this) {
3815            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3816            if (r == null) {
3817                return;
3818            }
3819            r.reportFullyDrawnLocked();
3820        }
3821    }
3822
3823    @Override
3824    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3825        synchronized (this) {
3826            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3827            if (r == null) {
3828                return;
3829            }
3830            if (r.task != null && r.task.mResizeable) {
3831                // Fixed screen orientation isn't supported with resizeable activities.
3832                return;
3833            }
3834            final long origId = Binder.clearCallingIdentity();
3835            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3836            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3837                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3838            if (config != null) {
3839                r.frozenBeforeDestroy = true;
3840                if (!updateConfigurationLocked(config, r, false, false)) {
3841                    mStackSupervisor.resumeTopActivitiesLocked();
3842                }
3843            }
3844            Binder.restoreCallingIdentity(origId);
3845        }
3846    }
3847
3848    @Override
3849    public int getRequestedOrientation(IBinder token) {
3850        synchronized (this) {
3851            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3852            if (r == null) {
3853                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3854            }
3855            return mWindowManager.getAppOrientation(r.appToken);
3856        }
3857    }
3858
3859    /**
3860     * This is the internal entry point for handling Activity.finish().
3861     *
3862     * @param token The Binder token referencing the Activity we want to finish.
3863     * @param resultCode Result code, if any, from this Activity.
3864     * @param resultData Result data (Intent), if any, from this Activity.
3865     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3866     *            the root Activity in the task.
3867     *
3868     * @return Returns true if the activity successfully finished, or false if it is still running.
3869     */
3870    @Override
3871    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3872            boolean finishTask) {
3873        // Refuse possible leaked file descriptors
3874        if (resultData != null && resultData.hasFileDescriptors() == true) {
3875            throw new IllegalArgumentException("File descriptors passed in Intent");
3876        }
3877
3878        synchronized(this) {
3879            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3880            if (r == null) {
3881                return true;
3882            }
3883            // Keep track of the root activity of the task before we finish it
3884            TaskRecord tr = r.task;
3885            ActivityRecord rootR = tr.getRootActivity();
3886            if (rootR == null) {
3887                Slog.w(TAG, "Finishing task with all activities already finished");
3888            }
3889            // Do not allow task to finish in Lock Task mode.
3890            if (tr == mStackSupervisor.mLockTaskModeTask) {
3891                if (rootR == r) {
3892                    Slog.i(TAG, "Not finishing task in lock task mode");
3893                    mStackSupervisor.showLockTaskToast();
3894                    return false;
3895                }
3896            }
3897            if (mController != null) {
3898                // Find the first activity that is not finishing.
3899                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3900                if (next != null) {
3901                    // ask watcher if this is allowed
3902                    boolean resumeOK = true;
3903                    try {
3904                        resumeOK = mController.activityResuming(next.packageName);
3905                    } catch (RemoteException e) {
3906                        mController = null;
3907                        Watchdog.getInstance().setActivityController(null);
3908                    }
3909
3910                    if (!resumeOK) {
3911                        Slog.i(TAG, "Not finishing activity because controller resumed");
3912                        return false;
3913                    }
3914                }
3915            }
3916            final long origId = Binder.clearCallingIdentity();
3917            try {
3918                boolean res;
3919                if (finishTask && r == rootR) {
3920                    // If requested, remove the task that is associated to this activity only if it
3921                    // was the root activity in the task. The result code and data is ignored
3922                    // because we don't support returning them across task boundaries.
3923                    res = removeTaskByIdLocked(tr.taskId, false);
3924                    if (!res) {
3925                        Slog.i(TAG, "Removing task failed to finish activity");
3926                    }
3927                } else {
3928                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3929                            resultData, "app-request", true);
3930                    if (!res) {
3931                        Slog.i(TAG, "Failed to finish by app-request");
3932                    }
3933                }
3934                return res;
3935            } finally {
3936                Binder.restoreCallingIdentity(origId);
3937            }
3938        }
3939    }
3940
3941    @Override
3942    public final void finishHeavyWeightApp() {
3943        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3944                != PackageManager.PERMISSION_GRANTED) {
3945            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3946                    + Binder.getCallingPid()
3947                    + ", uid=" + Binder.getCallingUid()
3948                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3949            Slog.w(TAG, msg);
3950            throw new SecurityException(msg);
3951        }
3952
3953        synchronized(this) {
3954            if (mHeavyWeightProcess == null) {
3955                return;
3956            }
3957
3958            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
3959            for (int i = 0; i < activities.size(); i++) {
3960                ActivityRecord r = activities.get(i);
3961                if (!r.finishing && r.isInStackLocked()) {
3962                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3963                            null, "finish-heavy", true);
3964                }
3965            }
3966
3967            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3968                    mHeavyWeightProcess.userId, 0));
3969            mHeavyWeightProcess = null;
3970        }
3971    }
3972
3973    @Override
3974    public void crashApplication(int uid, int initialPid, String packageName,
3975            String message) {
3976        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3977                != PackageManager.PERMISSION_GRANTED) {
3978            String msg = "Permission Denial: crashApplication() from pid="
3979                    + Binder.getCallingPid()
3980                    + ", uid=" + Binder.getCallingUid()
3981                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3982            Slog.w(TAG, msg);
3983            throw new SecurityException(msg);
3984        }
3985
3986        synchronized(this) {
3987            ProcessRecord proc = null;
3988
3989            // Figure out which process to kill.  We don't trust that initialPid
3990            // still has any relation to current pids, so must scan through the
3991            // list.
3992            synchronized (mPidsSelfLocked) {
3993                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3994                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3995                    if (p.uid != uid) {
3996                        continue;
3997                    }
3998                    if (p.pid == initialPid) {
3999                        proc = p;
4000                        break;
4001                    }
4002                    if (p.pkgList.containsKey(packageName)) {
4003                        proc = p;
4004                    }
4005                }
4006            }
4007
4008            if (proc == null) {
4009                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4010                        + " initialPid=" + initialPid
4011                        + " packageName=" + packageName);
4012                return;
4013            }
4014
4015            if (proc.thread != null) {
4016                if (proc.pid == Process.myPid()) {
4017                    Log.w(TAG, "crashApplication: trying to crash self!");
4018                    return;
4019                }
4020                long ident = Binder.clearCallingIdentity();
4021                try {
4022                    proc.thread.scheduleCrash(message);
4023                } catch (RemoteException e) {
4024                }
4025                Binder.restoreCallingIdentity(ident);
4026            }
4027        }
4028    }
4029
4030    @Override
4031    public final void finishSubActivity(IBinder token, String resultWho,
4032            int requestCode) {
4033        synchronized(this) {
4034            final long origId = Binder.clearCallingIdentity();
4035            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4036            if (r != null) {
4037                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4038            }
4039            Binder.restoreCallingIdentity(origId);
4040        }
4041    }
4042
4043    @Override
4044    public boolean finishActivityAffinity(IBinder token) {
4045        synchronized(this) {
4046            final long origId = Binder.clearCallingIdentity();
4047            try {
4048                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4049
4050                ActivityRecord rootR = r.task.getRootActivity();
4051                // Do not allow task to finish in Lock Task mode.
4052                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4053                    if (rootR == r) {
4054                        mStackSupervisor.showLockTaskToast();
4055                        return false;
4056                    }
4057                }
4058                boolean res = false;
4059                if (r != null) {
4060                    res = r.task.stack.finishActivityAffinityLocked(r);
4061                }
4062                return res;
4063            } finally {
4064                Binder.restoreCallingIdentity(origId);
4065            }
4066        }
4067    }
4068
4069    @Override
4070    public void finishVoiceTask(IVoiceInteractionSession session) {
4071        synchronized(this) {
4072            final long origId = Binder.clearCallingIdentity();
4073            try {
4074                mStackSupervisor.finishVoiceTask(session);
4075            } finally {
4076                Binder.restoreCallingIdentity(origId);
4077            }
4078        }
4079
4080    }
4081
4082    @Override
4083    public boolean releaseActivityInstance(IBinder token) {
4084        synchronized(this) {
4085            final long origId = Binder.clearCallingIdentity();
4086            try {
4087                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4088                if (r == null) {
4089                    return false;
4090                }
4091                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4092            } finally {
4093                Binder.restoreCallingIdentity(origId);
4094            }
4095        }
4096    }
4097
4098    @Override
4099    public void releaseSomeActivities(IApplicationThread appInt) {
4100        synchronized(this) {
4101            final long origId = Binder.clearCallingIdentity();
4102            try {
4103                ProcessRecord app = getRecordForAppLocked(appInt);
4104                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4105            } finally {
4106                Binder.restoreCallingIdentity(origId);
4107            }
4108        }
4109    }
4110
4111    @Override
4112    public boolean willActivityBeVisible(IBinder token) {
4113        synchronized(this) {
4114            ActivityStack stack = ActivityRecord.getStackLocked(token);
4115            if (stack != null) {
4116                return stack.willActivityBeVisibleLocked(token);
4117            }
4118            return false;
4119        }
4120    }
4121
4122    @Override
4123    public void overridePendingTransition(IBinder token, String packageName,
4124            int enterAnim, int exitAnim) {
4125        synchronized(this) {
4126            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4127            if (self == null) {
4128                return;
4129            }
4130
4131            final long origId = Binder.clearCallingIdentity();
4132
4133            if (self.state == ActivityState.RESUMED
4134                    || self.state == ActivityState.PAUSING) {
4135                mWindowManager.overridePendingAppTransition(packageName,
4136                        enterAnim, exitAnim, null);
4137            }
4138
4139            Binder.restoreCallingIdentity(origId);
4140        }
4141    }
4142
4143    /**
4144     * Main function for removing an existing process from the activity manager
4145     * as a result of that process going away.  Clears out all connections
4146     * to the process.
4147     */
4148    private final void handleAppDiedLocked(ProcessRecord app,
4149            boolean restarting, boolean allowRestart) {
4150        int pid = app.pid;
4151        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4152        if (!kept && !restarting) {
4153            removeLruProcessLocked(app);
4154            if (pid > 0) {
4155                ProcessList.remove(pid);
4156            }
4157        }
4158
4159        if (mProfileProc == app) {
4160            clearProfilerLocked();
4161        }
4162
4163        // Remove this application's activities from active lists.
4164        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4165
4166        app.activities.clear();
4167
4168        if (app.instrumentationClass != null) {
4169            Slog.w(TAG, "Crash of app " + app.processName
4170                  + " running instrumentation " + app.instrumentationClass);
4171            Bundle info = new Bundle();
4172            info.putString("shortMsg", "Process crashed.");
4173            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4174        }
4175
4176        if (!restarting) {
4177            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4178                // If there was nothing to resume, and we are not already
4179                // restarting this process, but there is a visible activity that
4180                // is hosted by the process...  then make sure all visible
4181                // activities are running, taking care of restarting this
4182                // process.
4183                if (hasVisibleActivities) {
4184                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4185                }
4186            }
4187        }
4188    }
4189
4190    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4191        IBinder threadBinder = thread.asBinder();
4192        // Find the application record.
4193        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4194            ProcessRecord rec = mLruProcesses.get(i);
4195            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4196                return i;
4197            }
4198        }
4199        return -1;
4200    }
4201
4202    final ProcessRecord getRecordForAppLocked(
4203            IApplicationThread thread) {
4204        if (thread == null) {
4205            return null;
4206        }
4207
4208        int appIndex = getLRURecordIndexForAppLocked(thread);
4209        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4210    }
4211
4212    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4213        // If there are no longer any background processes running,
4214        // and the app that died was not running instrumentation,
4215        // then tell everyone we are now low on memory.
4216        boolean haveBg = false;
4217        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4218            ProcessRecord rec = mLruProcesses.get(i);
4219            if (rec.thread != null
4220                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4221                haveBg = true;
4222                break;
4223            }
4224        }
4225
4226        if (!haveBg) {
4227            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4228            if (doReport) {
4229                long now = SystemClock.uptimeMillis();
4230                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4231                    doReport = false;
4232                } else {
4233                    mLastMemUsageReportTime = now;
4234                }
4235            }
4236            final ArrayList<ProcessMemInfo> memInfos
4237                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4238            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4239            long now = SystemClock.uptimeMillis();
4240            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4241                ProcessRecord rec = mLruProcesses.get(i);
4242                if (rec == dyingProc || rec.thread == null) {
4243                    continue;
4244                }
4245                if (doReport) {
4246                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4247                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4248                }
4249                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4250                    // The low memory report is overriding any current
4251                    // state for a GC request.  Make sure to do
4252                    // heavy/important/visible/foreground processes first.
4253                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4254                        rec.lastRequestedGc = 0;
4255                    } else {
4256                        rec.lastRequestedGc = rec.lastLowMemory;
4257                    }
4258                    rec.reportLowMemory = true;
4259                    rec.lastLowMemory = now;
4260                    mProcessesToGc.remove(rec);
4261                    addProcessToGcListLocked(rec);
4262                }
4263            }
4264            if (doReport) {
4265                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4266                mHandler.sendMessage(msg);
4267            }
4268            scheduleAppGcsLocked();
4269        }
4270    }
4271
4272    final void appDiedLocked(ProcessRecord app) {
4273       appDiedLocked(app, app.pid, app.thread);
4274    }
4275
4276    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4277        // First check if this ProcessRecord is actually active for the pid.
4278        synchronized (mPidsSelfLocked) {
4279            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4280            if (curProc != app) {
4281                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4282                return;
4283            }
4284        }
4285
4286        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4287        synchronized (stats) {
4288            stats.noteProcessDiedLocked(app.info.uid, pid);
4289        }
4290
4291        if (!app.killed) {
4292            Process.killProcessQuiet(pid);
4293            Process.killProcessGroup(app.info.uid, pid);
4294            app.killed = true;
4295        }
4296
4297        // Clean up already done if the process has been re-started.
4298        if (app.pid == pid && app.thread != null &&
4299                app.thread.asBinder() == thread.asBinder()) {
4300            boolean doLowMem = app.instrumentationClass == null;
4301            boolean doOomAdj = doLowMem;
4302            if (!app.killedByAm) {
4303                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4304                        + ") has died");
4305                mAllowLowerMemLevel = true;
4306            } else {
4307                // Note that we always want to do oom adj to update our state with the
4308                // new number of procs.
4309                mAllowLowerMemLevel = false;
4310                doLowMem = false;
4311            }
4312            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4313            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4314                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4315            handleAppDiedLocked(app, false, true);
4316
4317            if (doOomAdj) {
4318                updateOomAdjLocked();
4319            }
4320            if (doLowMem) {
4321                doLowMemReportIfNeededLocked(app);
4322            }
4323        } else if (app.pid != pid) {
4324            // A new process has already been started.
4325            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4326                    + ") has died and restarted (pid " + app.pid + ").");
4327            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4328        } else if (DEBUG_PROCESSES) {
4329            Slog.d(TAG, "Received spurious death notification for thread "
4330                    + thread.asBinder());
4331        }
4332    }
4333
4334    /**
4335     * If a stack trace dump file is configured, dump process stack traces.
4336     * @param clearTraces causes the dump file to be erased prior to the new
4337     *    traces being written, if true; when false, the new traces will be
4338     *    appended to any existing file content.
4339     * @param firstPids of dalvik VM processes to dump stack traces for first
4340     * @param lastPids of dalvik VM processes to dump stack traces for last
4341     * @param nativeProcs optional list of native process names to dump stack crawls
4342     * @return file containing stack traces, or null if no dump file is configured
4343     */
4344    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4345            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4346        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4347        if (tracesPath == null || tracesPath.length() == 0) {
4348            return null;
4349        }
4350
4351        File tracesFile = new File(tracesPath);
4352        try {
4353            File tracesDir = tracesFile.getParentFile();
4354            if (!tracesDir.exists()) {
4355                tracesDir.mkdirs();
4356                if (!SELinux.restorecon(tracesDir)) {
4357                    return null;
4358                }
4359            }
4360            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4361
4362            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4363            tracesFile.createNewFile();
4364            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4365        } catch (IOException e) {
4366            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4367            return null;
4368        }
4369
4370        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4371        return tracesFile;
4372    }
4373
4374    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4375            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4376        // Use a FileObserver to detect when traces finish writing.
4377        // The order of traces is considered important to maintain for legibility.
4378        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4379            @Override
4380            public synchronized void onEvent(int event, String path) { notify(); }
4381        };
4382
4383        try {
4384            observer.startWatching();
4385
4386            // First collect all of the stacks of the most important pids.
4387            if (firstPids != null) {
4388                try {
4389                    int num = firstPids.size();
4390                    for (int i = 0; i < num; i++) {
4391                        synchronized (observer) {
4392                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4393                            observer.wait(200);  // Wait for write-close, give up after 200msec
4394                        }
4395                    }
4396                } catch (InterruptedException e) {
4397                    Slog.wtf(TAG, e);
4398                }
4399            }
4400
4401            // Next collect the stacks of the native pids
4402            if (nativeProcs != null) {
4403                int[] pids = Process.getPidsForCommands(nativeProcs);
4404                if (pids != null) {
4405                    for (int pid : pids) {
4406                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4407                    }
4408                }
4409            }
4410
4411            // Lastly, measure CPU usage.
4412            if (processCpuTracker != null) {
4413                processCpuTracker.init();
4414                System.gc();
4415                processCpuTracker.update();
4416                try {
4417                    synchronized (processCpuTracker) {
4418                        processCpuTracker.wait(500); // measure over 1/2 second.
4419                    }
4420                } catch (InterruptedException e) {
4421                }
4422                processCpuTracker.update();
4423
4424                // We'll take the stack crawls of just the top apps using CPU.
4425                final int N = processCpuTracker.countWorkingStats();
4426                int numProcs = 0;
4427                for (int i=0; i<N && numProcs<5; i++) {
4428                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4429                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4430                        numProcs++;
4431                        try {
4432                            synchronized (observer) {
4433                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4434                                observer.wait(200);  // Wait for write-close, give up after 200msec
4435                            }
4436                        } catch (InterruptedException e) {
4437                            Slog.wtf(TAG, e);
4438                        }
4439
4440                    }
4441                }
4442            }
4443        } finally {
4444            observer.stopWatching();
4445        }
4446    }
4447
4448    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4449        if (true || IS_USER_BUILD) {
4450            return;
4451        }
4452        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4453        if (tracesPath == null || tracesPath.length() == 0) {
4454            return;
4455        }
4456
4457        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4458        StrictMode.allowThreadDiskWrites();
4459        try {
4460            final File tracesFile = new File(tracesPath);
4461            final File tracesDir = tracesFile.getParentFile();
4462            final File tracesTmp = new File(tracesDir, "__tmp__");
4463            try {
4464                if (!tracesDir.exists()) {
4465                    tracesDir.mkdirs();
4466                    if (!SELinux.restorecon(tracesDir.getPath())) {
4467                        return;
4468                    }
4469                }
4470                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4471
4472                if (tracesFile.exists()) {
4473                    tracesTmp.delete();
4474                    tracesFile.renameTo(tracesTmp);
4475                }
4476                StringBuilder sb = new StringBuilder();
4477                Time tobj = new Time();
4478                tobj.set(System.currentTimeMillis());
4479                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4480                sb.append(": ");
4481                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4482                sb.append(" since ");
4483                sb.append(msg);
4484                FileOutputStream fos = new FileOutputStream(tracesFile);
4485                fos.write(sb.toString().getBytes());
4486                if (app == null) {
4487                    fos.write("\n*** No application process!".getBytes());
4488                }
4489                fos.close();
4490                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4491            } catch (IOException e) {
4492                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4493                return;
4494            }
4495
4496            if (app != null) {
4497                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4498                firstPids.add(app.pid);
4499                dumpStackTraces(tracesPath, firstPids, null, null, null);
4500            }
4501
4502            File lastTracesFile = null;
4503            File curTracesFile = null;
4504            for (int i=9; i>=0; i--) {
4505                String name = String.format(Locale.US, "slow%02d.txt", i);
4506                curTracesFile = new File(tracesDir, name);
4507                if (curTracesFile.exists()) {
4508                    if (lastTracesFile != null) {
4509                        curTracesFile.renameTo(lastTracesFile);
4510                    } else {
4511                        curTracesFile.delete();
4512                    }
4513                }
4514                lastTracesFile = curTracesFile;
4515            }
4516            tracesFile.renameTo(curTracesFile);
4517            if (tracesTmp.exists()) {
4518                tracesTmp.renameTo(tracesFile);
4519            }
4520        } finally {
4521            StrictMode.setThreadPolicy(oldPolicy);
4522        }
4523    }
4524
4525    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4526            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4527        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4528        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4529
4530        if (mController != null) {
4531            try {
4532                // 0 == continue, -1 = kill process immediately
4533                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4534                if (res < 0 && app.pid != MY_PID) {
4535                    app.kill("anr", true);
4536                }
4537            } catch (RemoteException e) {
4538                mController = null;
4539                Watchdog.getInstance().setActivityController(null);
4540            }
4541        }
4542
4543        long anrTime = SystemClock.uptimeMillis();
4544        if (MONITOR_CPU_USAGE) {
4545            updateCpuStatsNow();
4546        }
4547
4548        synchronized (this) {
4549            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4550            if (mShuttingDown) {
4551                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4552                return;
4553            } else if (app.notResponding) {
4554                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4555                return;
4556            } else if (app.crashing) {
4557                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4558                return;
4559            }
4560
4561            // In case we come through here for the same app before completing
4562            // this one, mark as anring now so we will bail out.
4563            app.notResponding = true;
4564
4565            // Log the ANR to the event log.
4566            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4567                    app.processName, app.info.flags, annotation);
4568
4569            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4570            firstPids.add(app.pid);
4571
4572            int parentPid = app.pid;
4573            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4574            if (parentPid != app.pid) firstPids.add(parentPid);
4575
4576            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4577
4578            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4579                ProcessRecord r = mLruProcesses.get(i);
4580                if (r != null && r.thread != null) {
4581                    int pid = r.pid;
4582                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4583                        if (r.persistent) {
4584                            firstPids.add(pid);
4585                        } else {
4586                            lastPids.put(pid, Boolean.TRUE);
4587                        }
4588                    }
4589                }
4590            }
4591        }
4592
4593        // Log the ANR to the main log.
4594        StringBuilder info = new StringBuilder();
4595        info.setLength(0);
4596        info.append("ANR in ").append(app.processName);
4597        if (activity != null && activity.shortComponentName != null) {
4598            info.append(" (").append(activity.shortComponentName).append(")");
4599        }
4600        info.append("\n");
4601        info.append("PID: ").append(app.pid).append("\n");
4602        if (annotation != null) {
4603            info.append("Reason: ").append(annotation).append("\n");
4604        }
4605        if (parent != null && parent != activity) {
4606            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4607        }
4608
4609        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4610
4611        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4612                NATIVE_STACKS_OF_INTEREST);
4613
4614        String cpuInfo = null;
4615        if (MONITOR_CPU_USAGE) {
4616            updateCpuStatsNow();
4617            synchronized (mProcessCpuTracker) {
4618                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4619            }
4620            info.append(processCpuTracker.printCurrentLoad());
4621            info.append(cpuInfo);
4622        }
4623
4624        info.append(processCpuTracker.printCurrentState(anrTime));
4625
4626        Slog.e(TAG, info.toString());
4627        if (tracesFile == null) {
4628            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4629            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4630        }
4631
4632        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4633                cpuInfo, tracesFile, null);
4634
4635        if (mController != null) {
4636            try {
4637                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4638                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4639                if (res != 0) {
4640                    if (res < 0 && app.pid != MY_PID) {
4641                        app.kill("anr", true);
4642                    } else {
4643                        synchronized (this) {
4644                            mServices.scheduleServiceTimeoutLocked(app);
4645                        }
4646                    }
4647                    return;
4648                }
4649            } catch (RemoteException e) {
4650                mController = null;
4651                Watchdog.getInstance().setActivityController(null);
4652            }
4653        }
4654
4655        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4656        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4657                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4658
4659        synchronized (this) {
4660            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
4661
4662            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4663                app.kill("bg anr", true);
4664                return;
4665            }
4666
4667            // Set the app's notResponding state, and look up the errorReportReceiver
4668            makeAppNotRespondingLocked(app,
4669                    activity != null ? activity.shortComponentName : null,
4670                    annotation != null ? "ANR " + annotation : "ANR",
4671                    info.toString());
4672
4673            // Bring up the infamous App Not Responding dialog
4674            Message msg = Message.obtain();
4675            HashMap<String, Object> map = new HashMap<String, Object>();
4676            msg.what = SHOW_NOT_RESPONDING_MSG;
4677            msg.obj = map;
4678            msg.arg1 = aboveSystem ? 1 : 0;
4679            map.put("app", app);
4680            if (activity != null) {
4681                map.put("activity", activity);
4682            }
4683
4684            mHandler.sendMessage(msg);
4685        }
4686    }
4687
4688    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4689        if (!mLaunchWarningShown) {
4690            mLaunchWarningShown = true;
4691            mHandler.post(new Runnable() {
4692                @Override
4693                public void run() {
4694                    synchronized (ActivityManagerService.this) {
4695                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4696                        d.show();
4697                        mHandler.postDelayed(new Runnable() {
4698                            @Override
4699                            public void run() {
4700                                synchronized (ActivityManagerService.this) {
4701                                    d.dismiss();
4702                                    mLaunchWarningShown = false;
4703                                }
4704                            }
4705                        }, 4000);
4706                    }
4707                }
4708            });
4709        }
4710    }
4711
4712    @Override
4713    public boolean clearApplicationUserData(final String packageName,
4714            final IPackageDataObserver observer, int userId) {
4715        enforceNotIsolatedCaller("clearApplicationUserData");
4716        int uid = Binder.getCallingUid();
4717        int pid = Binder.getCallingPid();
4718        userId = handleIncomingUser(pid, uid,
4719                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4720        long callingId = Binder.clearCallingIdentity();
4721        try {
4722            IPackageManager pm = AppGlobals.getPackageManager();
4723            int pkgUid = -1;
4724            synchronized(this) {
4725                try {
4726                    pkgUid = pm.getPackageUid(packageName, userId);
4727                } catch (RemoteException e) {
4728                }
4729                if (pkgUid == -1) {
4730                    Slog.w(TAG, "Invalid packageName: " + packageName);
4731                    if (observer != null) {
4732                        try {
4733                            observer.onRemoveCompleted(packageName, false);
4734                        } catch (RemoteException e) {
4735                            Slog.i(TAG, "Observer no longer exists.");
4736                        }
4737                    }
4738                    return false;
4739                }
4740                if (uid == pkgUid || checkComponentPermission(
4741                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4742                        pid, uid, -1, true)
4743                        == PackageManager.PERMISSION_GRANTED) {
4744                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4745                } else {
4746                    throw new SecurityException("PID " + pid + " does not have permission "
4747                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4748                                    + " of package " + packageName);
4749                }
4750
4751                // Remove all tasks match the cleared application package and user
4752                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4753                    final TaskRecord tr = mRecentTasks.get(i);
4754                    final String taskPackageName =
4755                            tr.getBaseIntent().getComponent().getPackageName();
4756                    if (tr.userId != userId) continue;
4757                    if (!taskPackageName.equals(packageName)) continue;
4758                    removeTaskByIdLocked(tr.taskId, false);
4759                }
4760            }
4761
4762            try {
4763                // Clear application user data
4764                pm.clearApplicationUserData(packageName, observer, userId);
4765
4766                synchronized(this) {
4767                    // Remove all permissions granted from/to this package
4768                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4769                }
4770
4771                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4772                        Uri.fromParts("package", packageName, null));
4773                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4774                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4775                        null, null, 0, null, null, null, false, false, userId);
4776            } catch (RemoteException e) {
4777            }
4778        } finally {
4779            Binder.restoreCallingIdentity(callingId);
4780        }
4781        return true;
4782    }
4783
4784    @Override
4785    public void killBackgroundProcesses(final String packageName, int userId) {
4786        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4787                != PackageManager.PERMISSION_GRANTED &&
4788                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4789                        != PackageManager.PERMISSION_GRANTED) {
4790            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4791                    + Binder.getCallingPid()
4792                    + ", uid=" + Binder.getCallingUid()
4793                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4794            Slog.w(TAG, msg);
4795            throw new SecurityException(msg);
4796        }
4797
4798        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4799                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4800        long callingId = Binder.clearCallingIdentity();
4801        try {
4802            IPackageManager pm = AppGlobals.getPackageManager();
4803            synchronized(this) {
4804                int appId = -1;
4805                try {
4806                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4807                } catch (RemoteException e) {
4808                }
4809                if (appId == -1) {
4810                    Slog.w(TAG, "Invalid packageName: " + packageName);
4811                    return;
4812                }
4813                killPackageProcessesLocked(packageName, appId, userId,
4814                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4815            }
4816        } finally {
4817            Binder.restoreCallingIdentity(callingId);
4818        }
4819    }
4820
4821    @Override
4822    public void killAllBackgroundProcesses() {
4823        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4824                != PackageManager.PERMISSION_GRANTED) {
4825            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4826                    + Binder.getCallingPid()
4827                    + ", uid=" + Binder.getCallingUid()
4828                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4829            Slog.w(TAG, msg);
4830            throw new SecurityException(msg);
4831        }
4832
4833        long callingId = Binder.clearCallingIdentity();
4834        try {
4835            synchronized(this) {
4836                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4837                final int NP = mProcessNames.getMap().size();
4838                for (int ip=0; ip<NP; ip++) {
4839                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4840                    final int NA = apps.size();
4841                    for (int ia=0; ia<NA; ia++) {
4842                        ProcessRecord app = apps.valueAt(ia);
4843                        if (app.persistent) {
4844                            // we don't kill persistent processes
4845                            continue;
4846                        }
4847                        if (app.removed) {
4848                            procs.add(app);
4849                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4850                            app.removed = true;
4851                            procs.add(app);
4852                        }
4853                    }
4854                }
4855
4856                int N = procs.size();
4857                for (int i=0; i<N; i++) {
4858                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4859                }
4860                mAllowLowerMemLevel = true;
4861                updateOomAdjLocked();
4862                doLowMemReportIfNeededLocked(null);
4863            }
4864        } finally {
4865            Binder.restoreCallingIdentity(callingId);
4866        }
4867    }
4868
4869    @Override
4870    public void forceStopPackage(final String packageName, int userId) {
4871        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4872                != PackageManager.PERMISSION_GRANTED) {
4873            String msg = "Permission Denial: forceStopPackage() from pid="
4874                    + Binder.getCallingPid()
4875                    + ", uid=" + Binder.getCallingUid()
4876                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4877            Slog.w(TAG, msg);
4878            throw new SecurityException(msg);
4879        }
4880        final int callingPid = Binder.getCallingPid();
4881        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4882                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4883        long callingId = Binder.clearCallingIdentity();
4884        try {
4885            IPackageManager pm = AppGlobals.getPackageManager();
4886            synchronized(this) {
4887                int[] users = userId == UserHandle.USER_ALL
4888                        ? getUsersLocked() : new int[] { userId };
4889                for (int user : users) {
4890                    int pkgUid = -1;
4891                    try {
4892                        pkgUid = pm.getPackageUid(packageName, user);
4893                    } catch (RemoteException e) {
4894                    }
4895                    if (pkgUid == -1) {
4896                        Slog.w(TAG, "Invalid packageName: " + packageName);
4897                        continue;
4898                    }
4899                    try {
4900                        pm.setPackageStoppedState(packageName, true, user);
4901                    } catch (RemoteException e) {
4902                    } catch (IllegalArgumentException e) {
4903                        Slog.w(TAG, "Failed trying to unstop package "
4904                                + packageName + ": " + e);
4905                    }
4906                    if (isUserRunningLocked(user, false)) {
4907                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4908                    }
4909                }
4910            }
4911        } finally {
4912            Binder.restoreCallingIdentity(callingId);
4913        }
4914    }
4915
4916    @Override
4917    public void addPackageDependency(String packageName) {
4918        synchronized (this) {
4919            int callingPid = Binder.getCallingPid();
4920            if (callingPid == Process.myPid()) {
4921                //  Yeah, um, no.
4922                return;
4923            }
4924            ProcessRecord proc;
4925            synchronized (mPidsSelfLocked) {
4926                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4927            }
4928            if (proc != null) {
4929                if (proc.pkgDeps == null) {
4930                    proc.pkgDeps = new ArraySet<String>(1);
4931                }
4932                proc.pkgDeps.add(packageName);
4933            }
4934        }
4935    }
4936
4937    /*
4938     * The pkg name and app id have to be specified.
4939     */
4940    @Override
4941    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4942        if (pkg == null) {
4943            return;
4944        }
4945        // Make sure the uid is valid.
4946        if (appid < 0) {
4947            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4948            return;
4949        }
4950        int callerUid = Binder.getCallingUid();
4951        // Only the system server can kill an application
4952        if (callerUid == Process.SYSTEM_UID) {
4953            // Post an aysnc message to kill the application
4954            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4955            msg.arg1 = appid;
4956            msg.arg2 = 0;
4957            Bundle bundle = new Bundle();
4958            bundle.putString("pkg", pkg);
4959            bundle.putString("reason", reason);
4960            msg.obj = bundle;
4961            mHandler.sendMessage(msg);
4962        } else {
4963            throw new SecurityException(callerUid + " cannot kill pkg: " +
4964                    pkg);
4965        }
4966    }
4967
4968    @Override
4969    public void closeSystemDialogs(String reason) {
4970        enforceNotIsolatedCaller("closeSystemDialogs");
4971
4972        final int pid = Binder.getCallingPid();
4973        final int uid = Binder.getCallingUid();
4974        final long origId = Binder.clearCallingIdentity();
4975        try {
4976            synchronized (this) {
4977                // Only allow this from foreground processes, so that background
4978                // applications can't abuse it to prevent system UI from being shown.
4979                if (uid >= Process.FIRST_APPLICATION_UID) {
4980                    ProcessRecord proc;
4981                    synchronized (mPidsSelfLocked) {
4982                        proc = mPidsSelfLocked.get(pid);
4983                    }
4984                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4985                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4986                                + " from background process " + proc);
4987                        return;
4988                    }
4989                }
4990                closeSystemDialogsLocked(reason);
4991            }
4992        } finally {
4993            Binder.restoreCallingIdentity(origId);
4994        }
4995    }
4996
4997    void closeSystemDialogsLocked(String reason) {
4998        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4999        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5000                | Intent.FLAG_RECEIVER_FOREGROUND);
5001        if (reason != null) {
5002            intent.putExtra("reason", reason);
5003        }
5004        mWindowManager.closeSystemDialogs(reason);
5005
5006        mStackSupervisor.closeSystemDialogsLocked();
5007
5008        broadcastIntentLocked(null, null, intent, null,
5009                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5010                Process.SYSTEM_UID, UserHandle.USER_ALL);
5011    }
5012
5013    @Override
5014    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5015        enforceNotIsolatedCaller("getProcessMemoryInfo");
5016        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5017        for (int i=pids.length-1; i>=0; i--) {
5018            ProcessRecord proc;
5019            int oomAdj;
5020            synchronized (this) {
5021                synchronized (mPidsSelfLocked) {
5022                    proc = mPidsSelfLocked.get(pids[i]);
5023                    oomAdj = proc != null ? proc.setAdj : 0;
5024                }
5025            }
5026            infos[i] = new Debug.MemoryInfo();
5027            Debug.getMemoryInfo(pids[i], infos[i]);
5028            if (proc != null) {
5029                synchronized (this) {
5030                    if (proc.thread != null && proc.setAdj == oomAdj) {
5031                        // Record this for posterity if the process has been stable.
5032                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5033                                infos[i].getTotalUss(), false, proc.pkgList);
5034                    }
5035                }
5036            }
5037        }
5038        return infos;
5039    }
5040
5041    @Override
5042    public long[] getProcessPss(int[] pids) {
5043        enforceNotIsolatedCaller("getProcessPss");
5044        long[] pss = new long[pids.length];
5045        for (int i=pids.length-1; i>=0; i--) {
5046            ProcessRecord proc;
5047            int oomAdj;
5048            synchronized (this) {
5049                synchronized (mPidsSelfLocked) {
5050                    proc = mPidsSelfLocked.get(pids[i]);
5051                    oomAdj = proc != null ? proc.setAdj : 0;
5052                }
5053            }
5054            long[] tmpUss = new long[1];
5055            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5056            if (proc != null) {
5057                synchronized (this) {
5058                    if (proc.thread != null && proc.setAdj == oomAdj) {
5059                        // Record this for posterity if the process has been stable.
5060                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5061                    }
5062                }
5063            }
5064        }
5065        return pss;
5066    }
5067
5068    @Override
5069    public void killApplicationProcess(String processName, int uid) {
5070        if (processName == null) {
5071            return;
5072        }
5073
5074        int callerUid = Binder.getCallingUid();
5075        // Only the system server can kill an application
5076        if (callerUid == Process.SYSTEM_UID) {
5077            synchronized (this) {
5078                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5079                if (app != null && app.thread != null) {
5080                    try {
5081                        app.thread.scheduleSuicide();
5082                    } catch (RemoteException e) {
5083                        // If the other end already died, then our work here is done.
5084                    }
5085                } else {
5086                    Slog.w(TAG, "Process/uid not found attempting kill of "
5087                            + processName + " / " + uid);
5088                }
5089            }
5090        } else {
5091            throw new SecurityException(callerUid + " cannot kill app process: " +
5092                    processName);
5093        }
5094    }
5095
5096    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5097        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5098                false, true, false, false, UserHandle.getUserId(uid), reason);
5099        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5100                Uri.fromParts("package", packageName, null));
5101        if (!mProcessesReady) {
5102            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5103                    | Intent.FLAG_RECEIVER_FOREGROUND);
5104        }
5105        intent.putExtra(Intent.EXTRA_UID, uid);
5106        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5107        broadcastIntentLocked(null, null, intent,
5108                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5109                false, false,
5110                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5111    }
5112
5113    private void forceStopUserLocked(int userId, String reason) {
5114        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5115        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5116        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5117                | Intent.FLAG_RECEIVER_FOREGROUND);
5118        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5119        broadcastIntentLocked(null, null, intent,
5120                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5121                false, false,
5122                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5123    }
5124
5125    private final boolean killPackageProcessesLocked(String packageName, int appId,
5126            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5127            boolean doit, boolean evenPersistent, String reason) {
5128        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5129
5130        // Remove all processes this package may have touched: all with the
5131        // same UID (except for the system or root user), and all whose name
5132        // matches the package name.
5133        final int NP = mProcessNames.getMap().size();
5134        for (int ip=0; ip<NP; ip++) {
5135            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5136            final int NA = apps.size();
5137            for (int ia=0; ia<NA; ia++) {
5138                ProcessRecord app = apps.valueAt(ia);
5139                if (app.persistent && !evenPersistent) {
5140                    // we don't kill persistent processes
5141                    continue;
5142                }
5143                if (app.removed) {
5144                    if (doit) {
5145                        procs.add(app);
5146                    }
5147                    continue;
5148                }
5149
5150                // Skip process if it doesn't meet our oom adj requirement.
5151                if (app.setAdj < minOomAdj) {
5152                    continue;
5153                }
5154
5155                // If no package is specified, we call all processes under the
5156                // give user id.
5157                if (packageName == null) {
5158                    if (app.userId != userId) {
5159                        continue;
5160                    }
5161                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5162                        continue;
5163                    }
5164                // Package has been specified, we want to hit all processes
5165                // that match it.  We need to qualify this by the processes
5166                // that are running under the specified app and user ID.
5167                } else {
5168                    final boolean isDep = app.pkgDeps != null
5169                            && app.pkgDeps.contains(packageName);
5170                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5171                        continue;
5172                    }
5173                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5174                        continue;
5175                    }
5176                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5177                        continue;
5178                    }
5179                }
5180
5181                // Process has passed all conditions, kill it!
5182                if (!doit) {
5183                    return true;
5184                }
5185                app.removed = true;
5186                procs.add(app);
5187            }
5188        }
5189
5190        int N = procs.size();
5191        for (int i=0; i<N; i++) {
5192            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5193        }
5194        updateOomAdjLocked();
5195        return N > 0;
5196    }
5197
5198    private final boolean forceStopPackageLocked(String name, int appId,
5199            boolean callerWillRestart, boolean purgeCache, boolean doit,
5200            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5201        int i;
5202        int N;
5203
5204        if (userId == UserHandle.USER_ALL && name == null) {
5205            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5206        }
5207
5208        if (appId < 0 && name != null) {
5209            try {
5210                appId = UserHandle.getAppId(
5211                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5212            } catch (RemoteException e) {
5213            }
5214        }
5215
5216        if (doit) {
5217            if (name != null) {
5218                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5219                        + " user=" + userId + ": " + reason);
5220            } else {
5221                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5222            }
5223
5224            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5225            for (int ip=pmap.size()-1; ip>=0; ip--) {
5226                SparseArray<Long> ba = pmap.valueAt(ip);
5227                for (i=ba.size()-1; i>=0; i--) {
5228                    boolean remove = false;
5229                    final int entUid = ba.keyAt(i);
5230                    if (name != null) {
5231                        if (userId == UserHandle.USER_ALL) {
5232                            if (UserHandle.getAppId(entUid) == appId) {
5233                                remove = true;
5234                            }
5235                        } else {
5236                            if (entUid == UserHandle.getUid(userId, appId)) {
5237                                remove = true;
5238                            }
5239                        }
5240                    } else if (UserHandle.getUserId(entUid) == userId) {
5241                        remove = true;
5242                    }
5243                    if (remove) {
5244                        ba.removeAt(i);
5245                    }
5246                }
5247                if (ba.size() == 0) {
5248                    pmap.removeAt(ip);
5249                }
5250            }
5251        }
5252
5253        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5254                -100, callerWillRestart, true, doit, evenPersistent,
5255                name == null ? ("stop user " + userId) : ("stop " + name));
5256
5257        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5258            if (!doit) {
5259                return true;
5260            }
5261            didSomething = true;
5262        }
5263
5264        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5265            if (!doit) {
5266                return true;
5267            }
5268            didSomething = true;
5269        }
5270
5271        if (name == null) {
5272            // Remove all sticky broadcasts from this user.
5273            mStickyBroadcasts.remove(userId);
5274        }
5275
5276        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5277        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5278                userId, providers)) {
5279            if (!doit) {
5280                return true;
5281            }
5282            didSomething = true;
5283        }
5284        N = providers.size();
5285        for (i=0; i<N; i++) {
5286            removeDyingProviderLocked(null, providers.get(i), true);
5287        }
5288
5289        // Remove transient permissions granted from/to this package/user
5290        removeUriPermissionsForPackageLocked(name, userId, false);
5291
5292        if (name == null || uninstalling) {
5293            // Remove pending intents.  For now we only do this when force
5294            // stopping users, because we have some problems when doing this
5295            // for packages -- app widgets are not currently cleaned up for
5296            // such packages, so they can be left with bad pending intents.
5297            if (mIntentSenderRecords.size() > 0) {
5298                Iterator<WeakReference<PendingIntentRecord>> it
5299                        = mIntentSenderRecords.values().iterator();
5300                while (it.hasNext()) {
5301                    WeakReference<PendingIntentRecord> wpir = it.next();
5302                    if (wpir == null) {
5303                        it.remove();
5304                        continue;
5305                    }
5306                    PendingIntentRecord pir = wpir.get();
5307                    if (pir == null) {
5308                        it.remove();
5309                        continue;
5310                    }
5311                    if (name == null) {
5312                        // Stopping user, remove all objects for the user.
5313                        if (pir.key.userId != userId) {
5314                            // Not the same user, skip it.
5315                            continue;
5316                        }
5317                    } else {
5318                        if (UserHandle.getAppId(pir.uid) != appId) {
5319                            // Different app id, skip it.
5320                            continue;
5321                        }
5322                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5323                            // Different user, skip it.
5324                            continue;
5325                        }
5326                        if (!pir.key.packageName.equals(name)) {
5327                            // Different package, skip it.
5328                            continue;
5329                        }
5330                    }
5331                    if (!doit) {
5332                        return true;
5333                    }
5334                    didSomething = true;
5335                    it.remove();
5336                    pir.canceled = true;
5337                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5338                        pir.key.activity.pendingResults.remove(pir.ref);
5339                    }
5340                }
5341            }
5342        }
5343
5344        if (doit) {
5345            if (purgeCache && name != null) {
5346                AttributeCache ac = AttributeCache.instance();
5347                if (ac != null) {
5348                    ac.removePackage(name);
5349                }
5350            }
5351            if (mBooted) {
5352                mStackSupervisor.resumeTopActivitiesLocked();
5353                mStackSupervisor.scheduleIdleLocked();
5354            }
5355        }
5356
5357        return didSomething;
5358    }
5359
5360    private final boolean removeProcessLocked(ProcessRecord app,
5361            boolean callerWillRestart, boolean allowRestart, String reason) {
5362        final String name = app.processName;
5363        final int uid = app.uid;
5364        if (DEBUG_PROCESSES) Slog.d(
5365            TAG, "Force removing proc " + app.toShortString() + " (" + name
5366            + "/" + uid + ")");
5367
5368        mProcessNames.remove(name, uid);
5369        mIsolatedProcesses.remove(app.uid);
5370        if (mHeavyWeightProcess == app) {
5371            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5372                    mHeavyWeightProcess.userId, 0));
5373            mHeavyWeightProcess = null;
5374        }
5375        boolean needRestart = false;
5376        if (app.pid > 0 && app.pid != MY_PID) {
5377            int pid = app.pid;
5378            synchronized (mPidsSelfLocked) {
5379                mPidsSelfLocked.remove(pid);
5380                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5381            }
5382            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5383            if (app.isolated) {
5384                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5385            }
5386            app.kill(reason, true);
5387            handleAppDiedLocked(app, true, allowRestart);
5388            removeLruProcessLocked(app);
5389
5390            if (app.persistent && !app.isolated) {
5391                if (!callerWillRestart) {
5392                    addAppLocked(app.info, false, null /* ABI override */);
5393                } else {
5394                    needRestart = true;
5395                }
5396            }
5397        } else {
5398            mRemovedProcesses.add(app);
5399        }
5400
5401        return needRestart;
5402    }
5403
5404    private final void processStartTimedOutLocked(ProcessRecord app) {
5405        final int pid = app.pid;
5406        boolean gone = false;
5407        synchronized (mPidsSelfLocked) {
5408            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5409            if (knownApp != null && knownApp.thread == null) {
5410                mPidsSelfLocked.remove(pid);
5411                gone = true;
5412            }
5413        }
5414
5415        if (gone) {
5416            Slog.w(TAG, "Process " + app + " failed to attach");
5417            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5418                    pid, app.uid, app.processName);
5419            mProcessNames.remove(app.processName, app.uid);
5420            mIsolatedProcesses.remove(app.uid);
5421            if (mHeavyWeightProcess == app) {
5422                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5423                        mHeavyWeightProcess.userId, 0));
5424                mHeavyWeightProcess = null;
5425            }
5426            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5427            if (app.isolated) {
5428                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5429            }
5430            // Take care of any launching providers waiting for this process.
5431            checkAppInLaunchingProvidersLocked(app, true);
5432            // Take care of any services that are waiting for the process.
5433            mServices.processStartTimedOutLocked(app);
5434            app.kill("start timeout", true);
5435            removeLruProcessLocked(app);
5436            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5437                Slog.w(TAG, "Unattached app died before backup, skipping");
5438                try {
5439                    IBackupManager bm = IBackupManager.Stub.asInterface(
5440                            ServiceManager.getService(Context.BACKUP_SERVICE));
5441                    bm.agentDisconnected(app.info.packageName);
5442                } catch (RemoteException e) {
5443                    // Can't happen; the backup manager is local
5444                }
5445            }
5446            if (isPendingBroadcastProcessLocked(pid)) {
5447                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5448                skipPendingBroadcastLocked(pid);
5449            }
5450        } else {
5451            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5452        }
5453    }
5454
5455    private final boolean attachApplicationLocked(IApplicationThread thread,
5456            int pid) {
5457
5458        // Find the application record that is being attached...  either via
5459        // the pid if we are running in multiple processes, or just pull the
5460        // next app record if we are emulating process with anonymous threads.
5461        ProcessRecord app;
5462        if (pid != MY_PID && pid >= 0) {
5463            synchronized (mPidsSelfLocked) {
5464                app = mPidsSelfLocked.get(pid);
5465            }
5466        } else {
5467            app = null;
5468        }
5469
5470        if (app == null) {
5471            Slog.w(TAG, "No pending application record for pid " + pid
5472                    + " (IApplicationThread " + thread + "); dropping process");
5473            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5474            if (pid > 0 && pid != MY_PID) {
5475                Process.killProcessQuiet(pid);
5476                //TODO: Process.killProcessGroup(app.info.uid, pid);
5477            } else {
5478                try {
5479                    thread.scheduleExit();
5480                } catch (Exception e) {
5481                    // Ignore exceptions.
5482                }
5483            }
5484            return false;
5485        }
5486
5487        // If this application record is still attached to a previous
5488        // process, clean it up now.
5489        if (app.thread != null) {
5490            handleAppDiedLocked(app, true, true);
5491        }
5492
5493        // Tell the process all about itself.
5494
5495        if (DEBUG_ALL) Slog.v(
5496                TAG, "Binding process pid " + pid + " to record " + app);
5497
5498        final String processName = app.processName;
5499        try {
5500            AppDeathRecipient adr = new AppDeathRecipient(
5501                    app, pid, thread);
5502            thread.asBinder().linkToDeath(adr, 0);
5503            app.deathRecipient = adr;
5504        } catch (RemoteException e) {
5505            app.resetPackageList(mProcessStats);
5506            startProcessLocked(app, "link fail", processName);
5507            return false;
5508        }
5509
5510        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5511
5512        app.makeActive(thread, mProcessStats);
5513        app.curAdj = app.setAdj = -100;
5514        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5515        app.forcingToForeground = null;
5516        updateProcessForegroundLocked(app, false, false);
5517        app.hasShownUi = false;
5518        app.debugging = false;
5519        app.cached = false;
5520        app.killedByAm = false;
5521
5522        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5523
5524        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5525        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5526
5527        if (!normalMode) {
5528            Slog.i(TAG, "Launching preboot mode app: " + app);
5529        }
5530
5531        if (DEBUG_ALL) Slog.v(
5532            TAG, "New app record " + app
5533            + " thread=" + thread.asBinder() + " pid=" + pid);
5534        try {
5535            int testMode = IApplicationThread.DEBUG_OFF;
5536            if (mDebugApp != null && mDebugApp.equals(processName)) {
5537                testMode = mWaitForDebugger
5538                    ? IApplicationThread.DEBUG_WAIT
5539                    : IApplicationThread.DEBUG_ON;
5540                app.debugging = true;
5541                if (mDebugTransient) {
5542                    mDebugApp = mOrigDebugApp;
5543                    mWaitForDebugger = mOrigWaitForDebugger;
5544                }
5545            }
5546            String profileFile = app.instrumentationProfileFile;
5547            ParcelFileDescriptor profileFd = null;
5548            int samplingInterval = 0;
5549            boolean profileAutoStop = false;
5550            if (mProfileApp != null && mProfileApp.equals(processName)) {
5551                mProfileProc = app;
5552                profileFile = mProfileFile;
5553                profileFd = mProfileFd;
5554                samplingInterval = mSamplingInterval;
5555                profileAutoStop = mAutoStopProfiler;
5556            }
5557            boolean enableOpenGlTrace = false;
5558            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5559                enableOpenGlTrace = true;
5560                mOpenGlTraceApp = null;
5561            }
5562
5563            // If the app is being launched for restore or full backup, set it up specially
5564            boolean isRestrictedBackupMode = false;
5565            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5566                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5567                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5568                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5569            }
5570
5571            ensurePackageDexOpt(app.instrumentationInfo != null
5572                    ? app.instrumentationInfo.packageName
5573                    : app.info.packageName);
5574            if (app.instrumentationClass != null) {
5575                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5576            }
5577            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5578                    + processName + " with config " + mConfiguration);
5579            ApplicationInfo appInfo = app.instrumentationInfo != null
5580                    ? app.instrumentationInfo : app.info;
5581            app.compat = compatibilityInfoForPackageLocked(appInfo);
5582            if (profileFd != null) {
5583                profileFd = profileFd.dup();
5584            }
5585            ProfilerInfo profilerInfo = profileFile == null ? null
5586                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5587            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5588                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5589                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5590                    isRestrictedBackupMode || !normalMode, app.persistent,
5591                    new Configuration(mConfiguration), app.compat,
5592                    getCommonServicesLocked(app.isolated),
5593                    mCoreSettingsObserver.getCoreSettingsLocked());
5594            updateLruProcessLocked(app, false, null);
5595            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5596        } catch (Exception e) {
5597            // todo: Yikes!  What should we do?  For now we will try to
5598            // start another process, but that could easily get us in
5599            // an infinite loop of restarting processes...
5600            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5601
5602            app.resetPackageList(mProcessStats);
5603            app.unlinkDeathRecipient();
5604            startProcessLocked(app, "bind fail", processName);
5605            return false;
5606        }
5607
5608        // Remove this record from the list of starting applications.
5609        mPersistentStartingProcesses.remove(app);
5610        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5611                "Attach application locked removing on hold: " + app);
5612        mProcessesOnHold.remove(app);
5613
5614        boolean badApp = false;
5615        boolean didSomething = false;
5616
5617        // See if the top visible activity is waiting to run in this process...
5618        if (normalMode) {
5619            try {
5620                if (mStackSupervisor.attachApplicationLocked(app)) {
5621                    didSomething = true;
5622                }
5623            } catch (Exception e) {
5624                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5625                badApp = true;
5626            }
5627        }
5628
5629        // Find any services that should be running in this process...
5630        if (!badApp) {
5631            try {
5632                didSomething |= mServices.attachApplicationLocked(app, processName);
5633            } catch (Exception e) {
5634                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5635                badApp = true;
5636            }
5637        }
5638
5639        // Check if a next-broadcast receiver is in this process...
5640        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5641            try {
5642                didSomething |= sendPendingBroadcastsLocked(app);
5643            } catch (Exception e) {
5644                // If the app died trying to launch the receiver we declare it 'bad'
5645                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
5646                badApp = true;
5647            }
5648        }
5649
5650        // Check whether the next backup agent is in this process...
5651        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5652            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
5653                    "New app is backup target, launching agent for " + app);
5654            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5655            try {
5656                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5657                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5658                        mBackupTarget.backupMode);
5659            } catch (Exception e) {
5660                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
5661                badApp = true;
5662            }
5663        }
5664
5665        if (badApp) {
5666            app.kill("error during init", true);
5667            handleAppDiedLocked(app, false, true);
5668            return false;
5669        }
5670
5671        if (!didSomething) {
5672            updateOomAdjLocked();
5673        }
5674
5675        return true;
5676    }
5677
5678    @Override
5679    public final void attachApplication(IApplicationThread thread) {
5680        synchronized (this) {
5681            int callingPid = Binder.getCallingPid();
5682            final long origId = Binder.clearCallingIdentity();
5683            attachApplicationLocked(thread, callingPid);
5684            Binder.restoreCallingIdentity(origId);
5685        }
5686    }
5687
5688    @Override
5689    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5690        final long origId = Binder.clearCallingIdentity();
5691        synchronized (this) {
5692            ActivityStack stack = ActivityRecord.getStackLocked(token);
5693            if (stack != null) {
5694                ActivityRecord r =
5695                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5696                if (stopProfiling) {
5697                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5698                        try {
5699                            mProfileFd.close();
5700                        } catch (IOException e) {
5701                        }
5702                        clearProfilerLocked();
5703                    }
5704                }
5705            }
5706        }
5707        Binder.restoreCallingIdentity(origId);
5708    }
5709
5710    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
5711        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
5712                finishBooting? 1 : 0, enableScreen ? 1 : 0));
5713    }
5714
5715    void enableScreenAfterBoot() {
5716        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5717                SystemClock.uptimeMillis());
5718        mWindowManager.enableScreenAfterBoot();
5719
5720        synchronized (this) {
5721            updateEventDispatchingLocked();
5722        }
5723    }
5724
5725    @Override
5726    public void showBootMessage(final CharSequence msg, final boolean always) {
5727        if (Binder.getCallingUid() != Process.myUid()) {
5728            // These days only the core system can call this, so apps can't get in
5729            // the way of what we show about running them.
5730        }
5731        mWindowManager.showBootMessage(msg, always);
5732    }
5733
5734    @Override
5735    public void keyguardWaitingForActivityDrawn() {
5736        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5737        final long token = Binder.clearCallingIdentity();
5738        try {
5739            synchronized (this) {
5740                if (DEBUG_LOCKSCREEN) logLockScreen("");
5741                mWindowManager.keyguardWaitingForActivityDrawn();
5742                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
5743                    mLockScreenShown = LOCK_SCREEN_LEAVING;
5744                    updateSleepIfNeededLocked();
5745                }
5746            }
5747        } finally {
5748            Binder.restoreCallingIdentity(token);
5749        }
5750    }
5751
5752    final void finishBooting() {
5753        synchronized (this) {
5754            if (!mBootAnimationComplete) {
5755                mCallFinishBooting = true;
5756                return;
5757            }
5758            mCallFinishBooting = false;
5759        }
5760
5761        ArraySet<String> completedIsas = new ArraySet<String>();
5762        for (String abi : Build.SUPPORTED_ABIS) {
5763            Process.establishZygoteConnectionForAbi(abi);
5764            final String instructionSet = VMRuntime.getInstructionSet(abi);
5765            if (!completedIsas.contains(instructionSet)) {
5766                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
5767                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
5768                }
5769                completedIsas.add(instructionSet);
5770            }
5771        }
5772
5773        IntentFilter pkgFilter = new IntentFilter();
5774        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5775        pkgFilter.addDataScheme("package");
5776        mContext.registerReceiver(new BroadcastReceiver() {
5777            @Override
5778            public void onReceive(Context context, Intent intent) {
5779                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5780                if (pkgs != null) {
5781                    for (String pkg : pkgs) {
5782                        synchronized (ActivityManagerService.this) {
5783                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
5784                                    0, "query restart")) {
5785                                setResultCode(Activity.RESULT_OK);
5786                                return;
5787                            }
5788                        }
5789                    }
5790                }
5791            }
5792        }, pkgFilter);
5793
5794        IntentFilter dumpheapFilter = new IntentFilter();
5795        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
5796        mContext.registerReceiver(new BroadcastReceiver() {
5797            @Override
5798            public void onReceive(Context context, Intent intent) {
5799                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
5800                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
5801                } else {
5802                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
5803                }
5804            }
5805        }, dumpheapFilter);
5806
5807        // Let system services know.
5808        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5809
5810        synchronized (this) {
5811            // Ensure that any processes we had put on hold are now started
5812            // up.
5813            final int NP = mProcessesOnHold.size();
5814            if (NP > 0) {
5815                ArrayList<ProcessRecord> procs =
5816                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5817                for (int ip=0; ip<NP; ip++) {
5818                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5819                            + procs.get(ip));
5820                    startProcessLocked(procs.get(ip), "on-hold", null);
5821                }
5822            }
5823
5824            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5825                // Start looking for apps that are abusing wake locks.
5826                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5827                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5828                // Tell anyone interested that we are done booting!
5829                SystemProperties.set("sys.boot_completed", "1");
5830
5831                // And trigger dev.bootcomplete if we are not showing encryption progress
5832                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
5833                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
5834                    SystemProperties.set("dev.bootcomplete", "1");
5835                }
5836                for (int i=0; i<mStartedUsers.size(); i++) {
5837                    UserStartedState uss = mStartedUsers.valueAt(i);
5838                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5839                        uss.mState = UserStartedState.STATE_RUNNING;
5840                        final int userId = mStartedUsers.keyAt(i);
5841                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5842                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5843                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5844                        broadcastIntentLocked(null, null, intent, null,
5845                                new IIntentReceiver.Stub() {
5846                                    @Override
5847                                    public void performReceive(Intent intent, int resultCode,
5848                                            String data, Bundle extras, boolean ordered,
5849                                            boolean sticky, int sendingUser) {
5850                                        synchronized (ActivityManagerService.this) {
5851                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5852                                                    true, false);
5853                                        }
5854                                    }
5855                                },
5856                                0, null, null,
5857                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5858                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5859                                userId);
5860                    }
5861                }
5862                scheduleStartProfilesLocked();
5863            }
5864        }
5865    }
5866
5867    @Override
5868    public void bootAnimationComplete() {
5869        final boolean callFinishBooting;
5870        synchronized (this) {
5871            callFinishBooting = mCallFinishBooting;
5872            mBootAnimationComplete = true;
5873        }
5874        if (callFinishBooting) {
5875            finishBooting();
5876        }
5877    }
5878
5879    @Override
5880    public void systemBackupRestored() {
5881        synchronized (this) {
5882            if (mSystemReady) {
5883                mTaskPersister.restoreTasksFromOtherDeviceLocked();
5884            } else {
5885                Slog.w(TAG, "System backup restored before system is ready");
5886            }
5887        }
5888    }
5889
5890    final void ensureBootCompleted() {
5891        boolean booting;
5892        boolean enableScreen;
5893        synchronized (this) {
5894            booting = mBooting;
5895            mBooting = false;
5896            enableScreen = !mBooted;
5897            mBooted = true;
5898        }
5899
5900        if (booting) {
5901            finishBooting();
5902        }
5903
5904        if (enableScreen) {
5905            enableScreenAfterBoot();
5906        }
5907    }
5908
5909    @Override
5910    public final void activityResumed(IBinder token) {
5911        final long origId = Binder.clearCallingIdentity();
5912        synchronized(this) {
5913            ActivityStack stack = ActivityRecord.getStackLocked(token);
5914            if (stack != null) {
5915                ActivityRecord.activityResumedLocked(token);
5916            }
5917        }
5918        Binder.restoreCallingIdentity(origId);
5919    }
5920
5921    @Override
5922    public final void activityPaused(IBinder token) {
5923        final long origId = Binder.clearCallingIdentity();
5924        synchronized(this) {
5925            ActivityStack stack = ActivityRecord.getStackLocked(token);
5926            if (stack != null) {
5927                stack.activityPausedLocked(token, false);
5928            }
5929        }
5930        Binder.restoreCallingIdentity(origId);
5931    }
5932
5933    @Override
5934    public final void activityStopped(IBinder token, Bundle icicle,
5935            PersistableBundle persistentState, CharSequence description) {
5936        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
5937
5938        // Refuse possible leaked file descriptors
5939        if (icicle != null && icicle.hasFileDescriptors()) {
5940            throw new IllegalArgumentException("File descriptors passed in Bundle");
5941        }
5942
5943        final long origId = Binder.clearCallingIdentity();
5944
5945        synchronized (this) {
5946            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5947            if (r != null) {
5948                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5949            }
5950        }
5951
5952        trimApplications();
5953
5954        Binder.restoreCallingIdentity(origId);
5955    }
5956
5957    @Override
5958    public final void activityDestroyed(IBinder token) {
5959        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5960        synchronized (this) {
5961            ActivityStack stack = ActivityRecord.getStackLocked(token);
5962            if (stack != null) {
5963                stack.activityDestroyedLocked(token, "activityDestroyed");
5964            }
5965        }
5966    }
5967
5968    @Override
5969    public final void backgroundResourcesReleased(IBinder token) {
5970        final long origId = Binder.clearCallingIdentity();
5971        try {
5972            synchronized (this) {
5973                ActivityStack stack = ActivityRecord.getStackLocked(token);
5974                if (stack != null) {
5975                    stack.backgroundResourcesReleased();
5976                }
5977            }
5978        } finally {
5979            Binder.restoreCallingIdentity(origId);
5980        }
5981    }
5982
5983    @Override
5984    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5985        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5986    }
5987
5988    @Override
5989    public final void notifyEnterAnimationComplete(IBinder token) {
5990        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5991    }
5992
5993    @Override
5994    public String getCallingPackage(IBinder token) {
5995        synchronized (this) {
5996            ActivityRecord r = getCallingRecordLocked(token);
5997            return r != null ? r.info.packageName : null;
5998        }
5999    }
6000
6001    @Override
6002    public ComponentName getCallingActivity(IBinder token) {
6003        synchronized (this) {
6004            ActivityRecord r = getCallingRecordLocked(token);
6005            return r != null ? r.intent.getComponent() : null;
6006        }
6007    }
6008
6009    private ActivityRecord getCallingRecordLocked(IBinder token) {
6010        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6011        if (r == null) {
6012            return null;
6013        }
6014        return r.resultTo;
6015    }
6016
6017    @Override
6018    public ComponentName getActivityClassForToken(IBinder token) {
6019        synchronized(this) {
6020            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6021            if (r == null) {
6022                return null;
6023            }
6024            return r.intent.getComponent();
6025        }
6026    }
6027
6028    @Override
6029    public String getPackageForToken(IBinder token) {
6030        synchronized(this) {
6031            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6032            if (r == null) {
6033                return null;
6034            }
6035            return r.packageName;
6036        }
6037    }
6038
6039    @Override
6040    public IIntentSender getIntentSender(int type,
6041            String packageName, IBinder token, String resultWho,
6042            int requestCode, Intent[] intents, String[] resolvedTypes,
6043            int flags, Bundle options, int userId) {
6044        enforceNotIsolatedCaller("getIntentSender");
6045        // Refuse possible leaked file descriptors
6046        if (intents != null) {
6047            if (intents.length < 1) {
6048                throw new IllegalArgumentException("Intents array length must be >= 1");
6049            }
6050            for (int i=0; i<intents.length; i++) {
6051                Intent intent = intents[i];
6052                if (intent != null) {
6053                    if (intent.hasFileDescriptors()) {
6054                        throw new IllegalArgumentException("File descriptors passed in Intent");
6055                    }
6056                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6057                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6058                        throw new IllegalArgumentException(
6059                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6060                    }
6061                    intents[i] = new Intent(intent);
6062                }
6063            }
6064            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6065                throw new IllegalArgumentException(
6066                        "Intent array length does not match resolvedTypes length");
6067            }
6068        }
6069        if (options != null) {
6070            if (options.hasFileDescriptors()) {
6071                throw new IllegalArgumentException("File descriptors passed in options");
6072            }
6073        }
6074
6075        synchronized(this) {
6076            int callingUid = Binder.getCallingUid();
6077            int origUserId = userId;
6078            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6079                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6080                    ALLOW_NON_FULL, "getIntentSender", null);
6081            if (origUserId == UserHandle.USER_CURRENT) {
6082                // We don't want to evaluate this until the pending intent is
6083                // actually executed.  However, we do want to always do the
6084                // security checking for it above.
6085                userId = UserHandle.USER_CURRENT;
6086            }
6087            try {
6088                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6089                    int uid = AppGlobals.getPackageManager()
6090                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6091                    if (!UserHandle.isSameApp(callingUid, uid)) {
6092                        String msg = "Permission Denial: getIntentSender() from pid="
6093                            + Binder.getCallingPid()
6094                            + ", uid=" + Binder.getCallingUid()
6095                            + ", (need uid=" + uid + ")"
6096                            + " is not allowed to send as package " + packageName;
6097                        Slog.w(TAG, msg);
6098                        throw new SecurityException(msg);
6099                    }
6100                }
6101
6102                return getIntentSenderLocked(type, packageName, callingUid, userId,
6103                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6104
6105            } catch (RemoteException e) {
6106                throw new SecurityException(e);
6107            }
6108        }
6109    }
6110
6111    IIntentSender getIntentSenderLocked(int type, String packageName,
6112            int callingUid, int userId, IBinder token, String resultWho,
6113            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6114            Bundle options) {
6115        if (DEBUG_MU)
6116            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6117        ActivityRecord activity = null;
6118        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6119            activity = ActivityRecord.isInStackLocked(token);
6120            if (activity == null) {
6121                return null;
6122            }
6123            if (activity.finishing) {
6124                return null;
6125            }
6126        }
6127
6128        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6129        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6130        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6131        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6132                |PendingIntent.FLAG_UPDATE_CURRENT);
6133
6134        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6135                type, packageName, activity, resultWho,
6136                requestCode, intents, resolvedTypes, flags, options, userId);
6137        WeakReference<PendingIntentRecord> ref;
6138        ref = mIntentSenderRecords.get(key);
6139        PendingIntentRecord rec = ref != null ? ref.get() : null;
6140        if (rec != null) {
6141            if (!cancelCurrent) {
6142                if (updateCurrent) {
6143                    if (rec.key.requestIntent != null) {
6144                        rec.key.requestIntent.replaceExtras(intents != null ?
6145                                intents[intents.length - 1] : null);
6146                    }
6147                    if (intents != null) {
6148                        intents[intents.length-1] = rec.key.requestIntent;
6149                        rec.key.allIntents = intents;
6150                        rec.key.allResolvedTypes = resolvedTypes;
6151                    } else {
6152                        rec.key.allIntents = null;
6153                        rec.key.allResolvedTypes = null;
6154                    }
6155                }
6156                return rec;
6157            }
6158            rec.canceled = true;
6159            mIntentSenderRecords.remove(key);
6160        }
6161        if (noCreate) {
6162            return rec;
6163        }
6164        rec = new PendingIntentRecord(this, key, callingUid);
6165        mIntentSenderRecords.put(key, rec.ref);
6166        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6167            if (activity.pendingResults == null) {
6168                activity.pendingResults
6169                        = new HashSet<WeakReference<PendingIntentRecord>>();
6170            }
6171            activity.pendingResults.add(rec.ref);
6172        }
6173        return rec;
6174    }
6175
6176    @Override
6177    public void cancelIntentSender(IIntentSender sender) {
6178        if (!(sender instanceof PendingIntentRecord)) {
6179            return;
6180        }
6181        synchronized(this) {
6182            PendingIntentRecord rec = (PendingIntentRecord)sender;
6183            try {
6184                int uid = AppGlobals.getPackageManager()
6185                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6186                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6187                    String msg = "Permission Denial: cancelIntentSender() from pid="
6188                        + Binder.getCallingPid()
6189                        + ", uid=" + Binder.getCallingUid()
6190                        + " is not allowed to cancel packges "
6191                        + rec.key.packageName;
6192                    Slog.w(TAG, msg);
6193                    throw new SecurityException(msg);
6194                }
6195            } catch (RemoteException e) {
6196                throw new SecurityException(e);
6197            }
6198            cancelIntentSenderLocked(rec, true);
6199        }
6200    }
6201
6202    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6203        rec.canceled = true;
6204        mIntentSenderRecords.remove(rec.key);
6205        if (cleanActivity && rec.key.activity != null) {
6206            rec.key.activity.pendingResults.remove(rec.ref);
6207        }
6208    }
6209
6210    @Override
6211    public String getPackageForIntentSender(IIntentSender pendingResult) {
6212        if (!(pendingResult instanceof PendingIntentRecord)) {
6213            return null;
6214        }
6215        try {
6216            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6217            return res.key.packageName;
6218        } catch (ClassCastException e) {
6219        }
6220        return null;
6221    }
6222
6223    @Override
6224    public int getUidForIntentSender(IIntentSender sender) {
6225        if (sender instanceof PendingIntentRecord) {
6226            try {
6227                PendingIntentRecord res = (PendingIntentRecord)sender;
6228                return res.uid;
6229            } catch (ClassCastException e) {
6230            }
6231        }
6232        return -1;
6233    }
6234
6235    @Override
6236    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6237        if (!(pendingResult instanceof PendingIntentRecord)) {
6238            return false;
6239        }
6240        try {
6241            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6242            if (res.key.allIntents == null) {
6243                return false;
6244            }
6245            for (int i=0; i<res.key.allIntents.length; i++) {
6246                Intent intent = res.key.allIntents[i];
6247                if (intent.getPackage() != null && intent.getComponent() != null) {
6248                    return false;
6249                }
6250            }
6251            return true;
6252        } catch (ClassCastException e) {
6253        }
6254        return false;
6255    }
6256
6257    @Override
6258    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6259        if (!(pendingResult instanceof PendingIntentRecord)) {
6260            return false;
6261        }
6262        try {
6263            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6264            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6265                return true;
6266            }
6267            return false;
6268        } catch (ClassCastException e) {
6269        }
6270        return false;
6271    }
6272
6273    @Override
6274    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6275        if (!(pendingResult instanceof PendingIntentRecord)) {
6276            return null;
6277        }
6278        try {
6279            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6280            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6281        } catch (ClassCastException e) {
6282        }
6283        return null;
6284    }
6285
6286    @Override
6287    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6288        if (!(pendingResult instanceof PendingIntentRecord)) {
6289            return null;
6290        }
6291        try {
6292            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6293            Intent intent = res.key.requestIntent;
6294            if (intent != null) {
6295                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6296                        || res.lastTagPrefix.equals(prefix))) {
6297                    return res.lastTag;
6298                }
6299                res.lastTagPrefix = prefix;
6300                StringBuilder sb = new StringBuilder(128);
6301                if (prefix != null) {
6302                    sb.append(prefix);
6303                }
6304                if (intent.getAction() != null) {
6305                    sb.append(intent.getAction());
6306                } else if (intent.getComponent() != null) {
6307                    intent.getComponent().appendShortString(sb);
6308                } else {
6309                    sb.append("?");
6310                }
6311                return res.lastTag = sb.toString();
6312            }
6313        } catch (ClassCastException e) {
6314        }
6315        return null;
6316    }
6317
6318    @Override
6319    public void setProcessLimit(int max) {
6320        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6321                "setProcessLimit()");
6322        synchronized (this) {
6323            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6324            mProcessLimitOverride = max;
6325        }
6326        trimApplications();
6327    }
6328
6329    @Override
6330    public int getProcessLimit() {
6331        synchronized (this) {
6332            return mProcessLimitOverride;
6333        }
6334    }
6335
6336    void foregroundTokenDied(ForegroundToken token) {
6337        synchronized (ActivityManagerService.this) {
6338            synchronized (mPidsSelfLocked) {
6339                ForegroundToken cur
6340                    = mForegroundProcesses.get(token.pid);
6341                if (cur != token) {
6342                    return;
6343                }
6344                mForegroundProcesses.remove(token.pid);
6345                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6346                if (pr == null) {
6347                    return;
6348                }
6349                pr.forcingToForeground = null;
6350                updateProcessForegroundLocked(pr, false, false);
6351            }
6352            updateOomAdjLocked();
6353        }
6354    }
6355
6356    @Override
6357    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6358        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6359                "setProcessForeground()");
6360        synchronized(this) {
6361            boolean changed = false;
6362
6363            synchronized (mPidsSelfLocked) {
6364                ProcessRecord pr = mPidsSelfLocked.get(pid);
6365                if (pr == null && isForeground) {
6366                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6367                    return;
6368                }
6369                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6370                if (oldToken != null) {
6371                    oldToken.token.unlinkToDeath(oldToken, 0);
6372                    mForegroundProcesses.remove(pid);
6373                    if (pr != null) {
6374                        pr.forcingToForeground = null;
6375                    }
6376                    changed = true;
6377                }
6378                if (isForeground && token != null) {
6379                    ForegroundToken newToken = new ForegroundToken() {
6380                        @Override
6381                        public void binderDied() {
6382                            foregroundTokenDied(this);
6383                        }
6384                    };
6385                    newToken.pid = pid;
6386                    newToken.token = token;
6387                    try {
6388                        token.linkToDeath(newToken, 0);
6389                        mForegroundProcesses.put(pid, newToken);
6390                        pr.forcingToForeground = token;
6391                        changed = true;
6392                    } catch (RemoteException e) {
6393                        // If the process died while doing this, we will later
6394                        // do the cleanup with the process death link.
6395                    }
6396                }
6397            }
6398
6399            if (changed) {
6400                updateOomAdjLocked();
6401            }
6402        }
6403    }
6404
6405    // =========================================================
6406    // PROCESS INFO
6407    // =========================================================
6408
6409    static class ProcessInfoService extends IProcessInfoService.Stub {
6410        final ActivityManagerService mActivityManagerService;
6411        ProcessInfoService(ActivityManagerService activityManagerService) {
6412            mActivityManagerService = activityManagerService;
6413        }
6414
6415        @Override
6416        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6417            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6418        }
6419    }
6420
6421    /**
6422     * For each PID in the given input array, write the current process state
6423     * for that process into the output array, or -1 to indicate that no
6424     * process with the given PID exists.
6425     */
6426    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6427        if (pids == null) {
6428            throw new NullPointerException("pids");
6429        } else if (states == null) {
6430            throw new NullPointerException("states");
6431        } else if (pids.length != states.length) {
6432            throw new IllegalArgumentException("input and output arrays have different lengths!");
6433        }
6434
6435        synchronized (mPidsSelfLocked) {
6436            for (int i = 0; i < pids.length; i++) {
6437                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6438                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6439                        pr.curProcState;
6440            }
6441        }
6442    }
6443
6444    // =========================================================
6445    // PERMISSIONS
6446    // =========================================================
6447
6448    static class PermissionController extends IPermissionController.Stub {
6449        ActivityManagerService mActivityManagerService;
6450        PermissionController(ActivityManagerService activityManagerService) {
6451            mActivityManagerService = activityManagerService;
6452        }
6453
6454        @Override
6455        public boolean checkPermission(String permission, int pid, int uid) {
6456            return mActivityManagerService.checkPermission(permission, pid,
6457                    uid) == PackageManager.PERMISSION_GRANTED;
6458        }
6459    }
6460
6461    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6462        @Override
6463        public int checkComponentPermission(String permission, int pid, int uid,
6464                int owningUid, boolean exported) {
6465            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6466                    owningUid, exported);
6467        }
6468
6469        @Override
6470        public Object getAMSLock() {
6471            return ActivityManagerService.this;
6472        }
6473    }
6474
6475    /**
6476     * This can be called with or without the global lock held.
6477     */
6478    int checkComponentPermission(String permission, int pid, int uid,
6479            int owningUid, boolean exported) {
6480        if (pid == MY_PID) {
6481            return PackageManager.PERMISSION_GRANTED;
6482        }
6483        return ActivityManager.checkComponentPermission(permission, uid,
6484                owningUid, exported);
6485    }
6486
6487    /**
6488     * As the only public entry point for permissions checking, this method
6489     * can enforce the semantic that requesting a check on a null global
6490     * permission is automatically denied.  (Internally a null permission
6491     * string is used when calling {@link #checkComponentPermission} in cases
6492     * when only uid-based security is needed.)
6493     *
6494     * This can be called with or without the global lock held.
6495     */
6496    @Override
6497    public int checkPermission(String permission, int pid, int uid) {
6498        if (permission == null) {
6499            return PackageManager.PERMISSION_DENIED;
6500        }
6501        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6502    }
6503
6504    @Override
6505    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6506        if (permission == null) {
6507            return PackageManager.PERMISSION_DENIED;
6508        }
6509
6510        // We might be performing an operation on behalf of an indirect binder
6511        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6512        // client identity accordingly before proceeding.
6513        Identity tlsIdentity = sCallerIdentity.get();
6514        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6515            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6516                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6517            uid = tlsIdentity.uid;
6518            pid = tlsIdentity.pid;
6519        }
6520
6521        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6522    }
6523
6524    /**
6525     * Binder IPC calls go through the public entry point.
6526     * This can be called with or without the global lock held.
6527     */
6528    int checkCallingPermission(String permission) {
6529        return checkPermission(permission,
6530                Binder.getCallingPid(),
6531                UserHandle.getAppId(Binder.getCallingUid()));
6532    }
6533
6534    /**
6535     * This can be called with or without the global lock held.
6536     */
6537    void enforceCallingPermission(String permission, String func) {
6538        if (checkCallingPermission(permission)
6539                == PackageManager.PERMISSION_GRANTED) {
6540            return;
6541        }
6542
6543        String msg = "Permission Denial: " + func + " from pid="
6544                + Binder.getCallingPid()
6545                + ", uid=" + Binder.getCallingUid()
6546                + " requires " + permission;
6547        Slog.w(TAG, msg);
6548        throw new SecurityException(msg);
6549    }
6550
6551    /**
6552     * Determine if UID is holding permissions required to access {@link Uri} in
6553     * the given {@link ProviderInfo}. Final permission checking is always done
6554     * in {@link ContentProvider}.
6555     */
6556    private final boolean checkHoldingPermissionsLocked(
6557            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6558        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6559                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6560        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6561            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6562                    != PERMISSION_GRANTED) {
6563                return false;
6564            }
6565        }
6566        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6567    }
6568
6569    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6570            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6571        if (pi.applicationInfo.uid == uid) {
6572            return true;
6573        } else if (!pi.exported) {
6574            return false;
6575        }
6576
6577        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6578        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6579        try {
6580            // check if target holds top-level <provider> permissions
6581            if (!readMet && pi.readPermission != null && considerUidPermissions
6582                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6583                readMet = true;
6584            }
6585            if (!writeMet && pi.writePermission != null && considerUidPermissions
6586                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6587                writeMet = true;
6588            }
6589
6590            // track if unprotected read/write is allowed; any denied
6591            // <path-permission> below removes this ability
6592            boolean allowDefaultRead = pi.readPermission == null;
6593            boolean allowDefaultWrite = pi.writePermission == null;
6594
6595            // check if target holds any <path-permission> that match uri
6596            final PathPermission[] pps = pi.pathPermissions;
6597            if (pps != null) {
6598                final String path = grantUri.uri.getPath();
6599                int i = pps.length;
6600                while (i > 0 && (!readMet || !writeMet)) {
6601                    i--;
6602                    PathPermission pp = pps[i];
6603                    if (pp.match(path)) {
6604                        if (!readMet) {
6605                            final String pprperm = pp.getReadPermission();
6606                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6607                                    + pprperm + " for " + pp.getPath()
6608                                    + ": match=" + pp.match(path)
6609                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6610                            if (pprperm != null) {
6611                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6612                                        == PERMISSION_GRANTED) {
6613                                    readMet = true;
6614                                } else {
6615                                    allowDefaultRead = false;
6616                                }
6617                            }
6618                        }
6619                        if (!writeMet) {
6620                            final String ppwperm = pp.getWritePermission();
6621                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6622                                    + ppwperm + " for " + pp.getPath()
6623                                    + ": match=" + pp.match(path)
6624                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6625                            if (ppwperm != null) {
6626                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6627                                        == PERMISSION_GRANTED) {
6628                                    writeMet = true;
6629                                } else {
6630                                    allowDefaultWrite = false;
6631                                }
6632                            }
6633                        }
6634                    }
6635                }
6636            }
6637
6638            // grant unprotected <provider> read/write, if not blocked by
6639            // <path-permission> above
6640            if (allowDefaultRead) readMet = true;
6641            if (allowDefaultWrite) writeMet = true;
6642
6643        } catch (RemoteException e) {
6644            return false;
6645        }
6646
6647        return readMet && writeMet;
6648    }
6649
6650    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6651        ProviderInfo pi = null;
6652        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6653        if (cpr != null) {
6654            pi = cpr.info;
6655        } else {
6656            try {
6657                pi = AppGlobals.getPackageManager().resolveContentProvider(
6658                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6659            } catch (RemoteException ex) {
6660            }
6661        }
6662        return pi;
6663    }
6664
6665    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6666        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6667        if (targetUris != null) {
6668            return targetUris.get(grantUri);
6669        }
6670        return null;
6671    }
6672
6673    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6674            String targetPkg, int targetUid, GrantUri grantUri) {
6675        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6676        if (targetUris == null) {
6677            targetUris = Maps.newArrayMap();
6678            mGrantedUriPermissions.put(targetUid, targetUris);
6679        }
6680
6681        UriPermission perm = targetUris.get(grantUri);
6682        if (perm == null) {
6683            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6684            targetUris.put(grantUri, perm);
6685        }
6686
6687        return perm;
6688    }
6689
6690    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6691            final int modeFlags) {
6692        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6693        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6694                : UriPermission.STRENGTH_OWNED;
6695
6696        // Root gets to do everything.
6697        if (uid == 0) {
6698            return true;
6699        }
6700
6701        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6702        if (perms == null) return false;
6703
6704        // First look for exact match
6705        final UriPermission exactPerm = perms.get(grantUri);
6706        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6707            return true;
6708        }
6709
6710        // No exact match, look for prefixes
6711        final int N = perms.size();
6712        for (int i = 0; i < N; i++) {
6713            final UriPermission perm = perms.valueAt(i);
6714            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6715                    && perm.getStrength(modeFlags) >= minStrength) {
6716                return true;
6717            }
6718        }
6719
6720        return false;
6721    }
6722
6723    /**
6724     * @param uri This uri must NOT contain an embedded userId.
6725     * @param userId The userId in which the uri is to be resolved.
6726     */
6727    @Override
6728    public int checkUriPermission(Uri uri, int pid, int uid,
6729            final int modeFlags, int userId, IBinder callerToken) {
6730        enforceNotIsolatedCaller("checkUriPermission");
6731
6732        // Another redirected-binder-call permissions check as in
6733        // {@link checkPermissionWithToken}.
6734        Identity tlsIdentity = sCallerIdentity.get();
6735        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6736            uid = tlsIdentity.uid;
6737            pid = tlsIdentity.pid;
6738        }
6739
6740        // Our own process gets to do everything.
6741        if (pid == MY_PID) {
6742            return PackageManager.PERMISSION_GRANTED;
6743        }
6744        synchronized (this) {
6745            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6746                    ? PackageManager.PERMISSION_GRANTED
6747                    : PackageManager.PERMISSION_DENIED;
6748        }
6749    }
6750
6751    /**
6752     * Check if the targetPkg can be granted permission to access uri by
6753     * the callingUid using the given modeFlags.  Throws a security exception
6754     * if callingUid is not allowed to do this.  Returns the uid of the target
6755     * if the URI permission grant should be performed; returns -1 if it is not
6756     * needed (for example targetPkg already has permission to access the URI).
6757     * If you already know the uid of the target, you can supply it in
6758     * lastTargetUid else set that to -1.
6759     */
6760    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6761            final int modeFlags, int lastTargetUid) {
6762        if (!Intent.isAccessUriMode(modeFlags)) {
6763            return -1;
6764        }
6765
6766        if (targetPkg != null) {
6767            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6768                    "Checking grant " + targetPkg + " permission to " + grantUri);
6769        }
6770
6771        final IPackageManager pm = AppGlobals.getPackageManager();
6772
6773        // If this is not a content: uri, we can't do anything with it.
6774        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6775            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6776                    "Can't grant URI permission for non-content URI: " + grantUri);
6777            return -1;
6778        }
6779
6780        final String authority = grantUri.uri.getAuthority();
6781        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6782        if (pi == null) {
6783            Slog.w(TAG, "No content provider found for permission check: " +
6784                    grantUri.uri.toSafeString());
6785            return -1;
6786        }
6787
6788        int targetUid = lastTargetUid;
6789        if (targetUid < 0 && targetPkg != null) {
6790            try {
6791                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6792                if (targetUid < 0) {
6793                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6794                            "Can't grant URI permission no uid for: " + targetPkg);
6795                    return -1;
6796                }
6797            } catch (RemoteException ex) {
6798                return -1;
6799            }
6800        }
6801
6802        if (targetUid >= 0) {
6803            // First...  does the target actually need this permission?
6804            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6805                // No need to grant the target this permission.
6806                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6807                        "Target " + targetPkg + " already has full permission to " + grantUri);
6808                return -1;
6809            }
6810        } else {
6811            // First...  there is no target package, so can anyone access it?
6812            boolean allowed = pi.exported;
6813            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6814                if (pi.readPermission != null) {
6815                    allowed = false;
6816                }
6817            }
6818            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6819                if (pi.writePermission != null) {
6820                    allowed = false;
6821                }
6822            }
6823            if (allowed) {
6824                return -1;
6825            }
6826        }
6827
6828        /* There is a special cross user grant if:
6829         * - The target is on another user.
6830         * - Apps on the current user can access the uri without any uid permissions.
6831         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6832         * grant uri permissions.
6833         */
6834        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6835                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6836                modeFlags, false /*without considering the uid permissions*/);
6837
6838        // Second...  is the provider allowing granting of URI permissions?
6839        if (!specialCrossUserGrant) {
6840            if (!pi.grantUriPermissions) {
6841                throw new SecurityException("Provider " + pi.packageName
6842                        + "/" + pi.name
6843                        + " does not allow granting of Uri permissions (uri "
6844                        + grantUri + ")");
6845            }
6846            if (pi.uriPermissionPatterns != null) {
6847                final int N = pi.uriPermissionPatterns.length;
6848                boolean allowed = false;
6849                for (int i=0; i<N; i++) {
6850                    if (pi.uriPermissionPatterns[i] != null
6851                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6852                        allowed = true;
6853                        break;
6854                    }
6855                }
6856                if (!allowed) {
6857                    throw new SecurityException("Provider " + pi.packageName
6858                            + "/" + pi.name
6859                            + " does not allow granting of permission to path of Uri "
6860                            + grantUri);
6861                }
6862            }
6863        }
6864
6865        // Third...  does the caller itself have permission to access
6866        // this uri?
6867        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6868            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6869                // Require they hold a strong enough Uri permission
6870                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6871                    throw new SecurityException("Uid " + callingUid
6872                            + " does not have permission to uri " + grantUri);
6873                }
6874            }
6875        }
6876        return targetUid;
6877    }
6878
6879    /**
6880     * @param uri This uri must NOT contain an embedded userId.
6881     * @param userId The userId in which the uri is to be resolved.
6882     */
6883    @Override
6884    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6885            final int modeFlags, int userId) {
6886        enforceNotIsolatedCaller("checkGrantUriPermission");
6887        synchronized(this) {
6888            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6889                    new GrantUri(userId, uri, false), modeFlags, -1);
6890        }
6891    }
6892
6893    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6894            final int modeFlags, UriPermissionOwner owner) {
6895        if (!Intent.isAccessUriMode(modeFlags)) {
6896            return;
6897        }
6898
6899        // So here we are: the caller has the assumed permission
6900        // to the uri, and the target doesn't.  Let's now give this to
6901        // the target.
6902
6903        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6904                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6905
6906        final String authority = grantUri.uri.getAuthority();
6907        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6908        if (pi == null) {
6909            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6910            return;
6911        }
6912
6913        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6914            grantUri.prefix = true;
6915        }
6916        final UriPermission perm = findOrCreateUriPermissionLocked(
6917                pi.packageName, targetPkg, targetUid, grantUri);
6918        perm.grantModes(modeFlags, owner);
6919    }
6920
6921    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6922            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6923        if (targetPkg == null) {
6924            throw new NullPointerException("targetPkg");
6925        }
6926        int targetUid;
6927        final IPackageManager pm = AppGlobals.getPackageManager();
6928        try {
6929            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6930        } catch (RemoteException ex) {
6931            return;
6932        }
6933
6934        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6935                targetUid);
6936        if (targetUid < 0) {
6937            return;
6938        }
6939
6940        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6941                owner);
6942    }
6943
6944    static class NeededUriGrants extends ArrayList<GrantUri> {
6945        final String targetPkg;
6946        final int targetUid;
6947        final int flags;
6948
6949        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6950            this.targetPkg = targetPkg;
6951            this.targetUid = targetUid;
6952            this.flags = flags;
6953        }
6954    }
6955
6956    /**
6957     * Like checkGrantUriPermissionLocked, but takes an Intent.
6958     */
6959    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6960            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6961        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6962                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6963                + " clip=" + (intent != null ? intent.getClipData() : null)
6964                + " from " + intent + "; flags=0x"
6965                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6966
6967        if (targetPkg == null) {
6968            throw new NullPointerException("targetPkg");
6969        }
6970
6971        if (intent == null) {
6972            return null;
6973        }
6974        Uri data = intent.getData();
6975        ClipData clip = intent.getClipData();
6976        if (data == null && clip == null) {
6977            return null;
6978        }
6979        // Default userId for uris in the intent (if they don't specify it themselves)
6980        int contentUserHint = intent.getContentUserHint();
6981        if (contentUserHint == UserHandle.USER_CURRENT) {
6982            contentUserHint = UserHandle.getUserId(callingUid);
6983        }
6984        final IPackageManager pm = AppGlobals.getPackageManager();
6985        int targetUid;
6986        if (needed != null) {
6987            targetUid = needed.targetUid;
6988        } else {
6989            try {
6990                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6991            } catch (RemoteException ex) {
6992                return null;
6993            }
6994            if (targetUid < 0) {
6995                if (DEBUG_URI_PERMISSION) {
6996                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6997                            + " on user " + targetUserId);
6998                }
6999                return null;
7000            }
7001        }
7002        if (data != null) {
7003            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7004            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7005                    targetUid);
7006            if (targetUid > 0) {
7007                if (needed == null) {
7008                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7009                }
7010                needed.add(grantUri);
7011            }
7012        }
7013        if (clip != null) {
7014            for (int i=0; i<clip.getItemCount(); i++) {
7015                Uri uri = clip.getItemAt(i).getUri();
7016                if (uri != null) {
7017                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7018                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7019                            targetUid);
7020                    if (targetUid > 0) {
7021                        if (needed == null) {
7022                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7023                        }
7024                        needed.add(grantUri);
7025                    }
7026                } else {
7027                    Intent clipIntent = clip.getItemAt(i).getIntent();
7028                    if (clipIntent != null) {
7029                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7030                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7031                        if (newNeeded != null) {
7032                            needed = newNeeded;
7033                        }
7034                    }
7035                }
7036            }
7037        }
7038
7039        return needed;
7040    }
7041
7042    /**
7043     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7044     */
7045    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7046            UriPermissionOwner owner) {
7047        if (needed != null) {
7048            for (int i=0; i<needed.size(); i++) {
7049                GrantUri grantUri = needed.get(i);
7050                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7051                        grantUri, needed.flags, owner);
7052            }
7053        }
7054    }
7055
7056    void grantUriPermissionFromIntentLocked(int callingUid,
7057            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7058        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7059                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7060        if (needed == null) {
7061            return;
7062        }
7063
7064        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7065    }
7066
7067    /**
7068     * @param uri This uri must NOT contain an embedded userId.
7069     * @param userId The userId in which the uri is to be resolved.
7070     */
7071    @Override
7072    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7073            final int modeFlags, int userId) {
7074        enforceNotIsolatedCaller("grantUriPermission");
7075        GrantUri grantUri = new GrantUri(userId, uri, false);
7076        synchronized(this) {
7077            final ProcessRecord r = getRecordForAppLocked(caller);
7078            if (r == null) {
7079                throw new SecurityException("Unable to find app for caller "
7080                        + caller
7081                        + " when granting permission to uri " + grantUri);
7082            }
7083            if (targetPkg == null) {
7084                throw new IllegalArgumentException("null target");
7085            }
7086            if (grantUri == null) {
7087                throw new IllegalArgumentException("null uri");
7088            }
7089
7090            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7091                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7092                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7093                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7094
7095            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7096                    UserHandle.getUserId(r.uid));
7097        }
7098    }
7099
7100    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7101        if (perm.modeFlags == 0) {
7102            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7103                    perm.targetUid);
7104            if (perms != null) {
7105                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7106                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7107
7108                perms.remove(perm.uri);
7109                if (perms.isEmpty()) {
7110                    mGrantedUriPermissions.remove(perm.targetUid);
7111                }
7112            }
7113        }
7114    }
7115
7116    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7117        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7118
7119        final IPackageManager pm = AppGlobals.getPackageManager();
7120        final String authority = grantUri.uri.getAuthority();
7121        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7122        if (pi == null) {
7123            Slog.w(TAG, "No content provider found for permission revoke: "
7124                    + grantUri.toSafeString());
7125            return;
7126        }
7127
7128        // Does the caller have this permission on the URI?
7129        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7130            // If they don't have direct access to the URI, then revoke any
7131            // ownerless URI permissions that have been granted to them.
7132            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7133            if (perms != null) {
7134                boolean persistChanged = false;
7135                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7136                    final UriPermission perm = it.next();
7137                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7138                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7139                        if (DEBUG_URI_PERMISSION)
7140                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7141                                    " permission to " + perm.uri);
7142                        persistChanged |= perm.revokeModes(
7143                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7144                        if (perm.modeFlags == 0) {
7145                            it.remove();
7146                        }
7147                    }
7148                }
7149                if (perms.isEmpty()) {
7150                    mGrantedUriPermissions.remove(callingUid);
7151                }
7152                if (persistChanged) {
7153                    schedulePersistUriGrants();
7154                }
7155            }
7156            return;
7157        }
7158
7159        boolean persistChanged = false;
7160
7161        // Go through all of the permissions and remove any that match.
7162        int N = mGrantedUriPermissions.size();
7163        for (int i = 0; i < N; i++) {
7164            final int targetUid = mGrantedUriPermissions.keyAt(i);
7165            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7166
7167            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7168                final UriPermission perm = it.next();
7169                if (perm.uri.sourceUserId == grantUri.sourceUserId
7170                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7171                    if (DEBUG_URI_PERMISSION)
7172                        Slog.v(TAG,
7173                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7174                    persistChanged |= perm.revokeModes(
7175                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7176                    if (perm.modeFlags == 0) {
7177                        it.remove();
7178                    }
7179                }
7180            }
7181
7182            if (perms.isEmpty()) {
7183                mGrantedUriPermissions.remove(targetUid);
7184                N--;
7185                i--;
7186            }
7187        }
7188
7189        if (persistChanged) {
7190            schedulePersistUriGrants();
7191        }
7192    }
7193
7194    /**
7195     * @param uri This uri must NOT contain an embedded userId.
7196     * @param userId The userId in which the uri is to be resolved.
7197     */
7198    @Override
7199    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7200            int userId) {
7201        enforceNotIsolatedCaller("revokeUriPermission");
7202        synchronized(this) {
7203            final ProcessRecord r = getRecordForAppLocked(caller);
7204            if (r == null) {
7205                throw new SecurityException("Unable to find app for caller "
7206                        + caller
7207                        + " when revoking permission to uri " + uri);
7208            }
7209            if (uri == null) {
7210                Slog.w(TAG, "revokeUriPermission: null uri");
7211                return;
7212            }
7213
7214            if (!Intent.isAccessUriMode(modeFlags)) {
7215                return;
7216            }
7217
7218            final String authority = uri.getAuthority();
7219            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7220            if (pi == null) {
7221                Slog.w(TAG, "No content provider found for permission revoke: "
7222                        + uri.toSafeString());
7223                return;
7224            }
7225
7226            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7227        }
7228    }
7229
7230    /**
7231     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7232     * given package.
7233     *
7234     * @param packageName Package name to match, or {@code null} to apply to all
7235     *            packages.
7236     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7237     *            to all users.
7238     * @param persistable If persistable grants should be removed.
7239     */
7240    private void removeUriPermissionsForPackageLocked(
7241            String packageName, int userHandle, boolean persistable) {
7242        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7243            throw new IllegalArgumentException("Must narrow by either package or user");
7244        }
7245
7246        boolean persistChanged = false;
7247
7248        int N = mGrantedUriPermissions.size();
7249        for (int i = 0; i < N; i++) {
7250            final int targetUid = mGrantedUriPermissions.keyAt(i);
7251            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7252
7253            // Only inspect grants matching user
7254            if (userHandle == UserHandle.USER_ALL
7255                    || userHandle == UserHandle.getUserId(targetUid)) {
7256                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7257                    final UriPermission perm = it.next();
7258
7259                    // Only inspect grants matching package
7260                    if (packageName == null || perm.sourcePkg.equals(packageName)
7261                            || perm.targetPkg.equals(packageName)) {
7262                        persistChanged |= perm.revokeModes(persistable
7263                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7264
7265                        // Only remove when no modes remain; any persisted grants
7266                        // will keep this alive.
7267                        if (perm.modeFlags == 0) {
7268                            it.remove();
7269                        }
7270                    }
7271                }
7272
7273                if (perms.isEmpty()) {
7274                    mGrantedUriPermissions.remove(targetUid);
7275                    N--;
7276                    i--;
7277                }
7278            }
7279        }
7280
7281        if (persistChanged) {
7282            schedulePersistUriGrants();
7283        }
7284    }
7285
7286    @Override
7287    public IBinder newUriPermissionOwner(String name) {
7288        enforceNotIsolatedCaller("newUriPermissionOwner");
7289        synchronized(this) {
7290            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7291            return owner.getExternalTokenLocked();
7292        }
7293    }
7294
7295    /**
7296     * @param uri This uri must NOT contain an embedded userId.
7297     * @param sourceUserId The userId in which the uri is to be resolved.
7298     * @param targetUserId The userId of the app that receives the grant.
7299     */
7300    @Override
7301    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7302            final int modeFlags, int sourceUserId, int targetUserId) {
7303        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7304                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7305        synchronized(this) {
7306            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7307            if (owner == null) {
7308                throw new IllegalArgumentException("Unknown owner: " + token);
7309            }
7310            if (fromUid != Binder.getCallingUid()) {
7311                if (Binder.getCallingUid() != Process.myUid()) {
7312                    // Only system code can grant URI permissions on behalf
7313                    // of other users.
7314                    throw new SecurityException("nice try");
7315                }
7316            }
7317            if (targetPkg == null) {
7318                throw new IllegalArgumentException("null target");
7319            }
7320            if (uri == null) {
7321                throw new IllegalArgumentException("null uri");
7322            }
7323
7324            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7325                    modeFlags, owner, targetUserId);
7326        }
7327    }
7328
7329    /**
7330     * @param uri This uri must NOT contain an embedded userId.
7331     * @param userId The userId in which the uri is to be resolved.
7332     */
7333    @Override
7334    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7335        synchronized(this) {
7336            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7337            if (owner == null) {
7338                throw new IllegalArgumentException("Unknown owner: " + token);
7339            }
7340
7341            if (uri == null) {
7342                owner.removeUriPermissionsLocked(mode);
7343            } else {
7344                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7345            }
7346        }
7347    }
7348
7349    private void schedulePersistUriGrants() {
7350        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7351            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7352                    10 * DateUtils.SECOND_IN_MILLIS);
7353        }
7354    }
7355
7356    private void writeGrantedUriPermissions() {
7357        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7358
7359        // Snapshot permissions so we can persist without lock
7360        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7361        synchronized (this) {
7362            final int size = mGrantedUriPermissions.size();
7363            for (int i = 0; i < size; i++) {
7364                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7365                for (UriPermission perm : perms.values()) {
7366                    if (perm.persistedModeFlags != 0) {
7367                        persist.add(perm.snapshot());
7368                    }
7369                }
7370            }
7371        }
7372
7373        FileOutputStream fos = null;
7374        try {
7375            fos = mGrantFile.startWrite();
7376
7377            XmlSerializer out = new FastXmlSerializer();
7378            out.setOutput(fos, "utf-8");
7379            out.startDocument(null, true);
7380            out.startTag(null, TAG_URI_GRANTS);
7381            for (UriPermission.Snapshot perm : persist) {
7382                out.startTag(null, TAG_URI_GRANT);
7383                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7384                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7385                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7386                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7387                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7388                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7389                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7390                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7391                out.endTag(null, TAG_URI_GRANT);
7392            }
7393            out.endTag(null, TAG_URI_GRANTS);
7394            out.endDocument();
7395
7396            mGrantFile.finishWrite(fos);
7397        } catch (IOException e) {
7398            if (fos != null) {
7399                mGrantFile.failWrite(fos);
7400            }
7401        }
7402    }
7403
7404    private void readGrantedUriPermissionsLocked() {
7405        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7406
7407        final long now = System.currentTimeMillis();
7408
7409        FileInputStream fis = null;
7410        try {
7411            fis = mGrantFile.openRead();
7412            final XmlPullParser in = Xml.newPullParser();
7413            in.setInput(fis, null);
7414
7415            int type;
7416            while ((type = in.next()) != END_DOCUMENT) {
7417                final String tag = in.getName();
7418                if (type == START_TAG) {
7419                    if (TAG_URI_GRANT.equals(tag)) {
7420                        final int sourceUserId;
7421                        final int targetUserId;
7422                        final int userHandle = readIntAttribute(in,
7423                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7424                        if (userHandle != UserHandle.USER_NULL) {
7425                            // For backwards compatibility.
7426                            sourceUserId = userHandle;
7427                            targetUserId = userHandle;
7428                        } else {
7429                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7430                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7431                        }
7432                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7433                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7434                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7435                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7436                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7437                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7438
7439                        // Sanity check that provider still belongs to source package
7440                        final ProviderInfo pi = getProviderInfoLocked(
7441                                uri.getAuthority(), sourceUserId);
7442                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7443                            int targetUid = -1;
7444                            try {
7445                                targetUid = AppGlobals.getPackageManager()
7446                                        .getPackageUid(targetPkg, targetUserId);
7447                            } catch (RemoteException e) {
7448                            }
7449                            if (targetUid != -1) {
7450                                final UriPermission perm = findOrCreateUriPermissionLocked(
7451                                        sourcePkg, targetPkg, targetUid,
7452                                        new GrantUri(sourceUserId, uri, prefix));
7453                                perm.initPersistedModes(modeFlags, createdTime);
7454                            }
7455                        } else {
7456                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7457                                    + " but instead found " + pi);
7458                        }
7459                    }
7460                }
7461            }
7462        } catch (FileNotFoundException e) {
7463            // Missing grants is okay
7464        } catch (IOException e) {
7465            Slog.wtf(TAG, "Failed reading Uri grants", e);
7466        } catch (XmlPullParserException e) {
7467            Slog.wtf(TAG, "Failed reading Uri grants", e);
7468        } finally {
7469            IoUtils.closeQuietly(fis);
7470        }
7471    }
7472
7473    /**
7474     * @param uri This uri must NOT contain an embedded userId.
7475     * @param userId The userId in which the uri is to be resolved.
7476     */
7477    @Override
7478    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7479        enforceNotIsolatedCaller("takePersistableUriPermission");
7480
7481        Preconditions.checkFlagsArgument(modeFlags,
7482                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7483
7484        synchronized (this) {
7485            final int callingUid = Binder.getCallingUid();
7486            boolean persistChanged = false;
7487            GrantUri grantUri = new GrantUri(userId, uri, false);
7488
7489            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7490                    new GrantUri(userId, uri, false));
7491            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7492                    new GrantUri(userId, uri, true));
7493
7494            final boolean exactValid = (exactPerm != null)
7495                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7496            final boolean prefixValid = (prefixPerm != null)
7497                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7498
7499            if (!(exactValid || prefixValid)) {
7500                throw new SecurityException("No persistable permission grants found for UID "
7501                        + callingUid + " and Uri " + grantUri.toSafeString());
7502            }
7503
7504            if (exactValid) {
7505                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7506            }
7507            if (prefixValid) {
7508                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7509            }
7510
7511            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7512
7513            if (persistChanged) {
7514                schedulePersistUriGrants();
7515            }
7516        }
7517    }
7518
7519    /**
7520     * @param uri This uri must NOT contain an embedded userId.
7521     * @param userId The userId in which the uri is to be resolved.
7522     */
7523    @Override
7524    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7525        enforceNotIsolatedCaller("releasePersistableUriPermission");
7526
7527        Preconditions.checkFlagsArgument(modeFlags,
7528                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7529
7530        synchronized (this) {
7531            final int callingUid = Binder.getCallingUid();
7532            boolean persistChanged = false;
7533
7534            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7535                    new GrantUri(userId, uri, false));
7536            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7537                    new GrantUri(userId, uri, true));
7538            if (exactPerm == null && prefixPerm == null) {
7539                throw new SecurityException("No permission grants found for UID " + callingUid
7540                        + " and Uri " + uri.toSafeString());
7541            }
7542
7543            if (exactPerm != null) {
7544                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7545                removeUriPermissionIfNeededLocked(exactPerm);
7546            }
7547            if (prefixPerm != null) {
7548                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7549                removeUriPermissionIfNeededLocked(prefixPerm);
7550            }
7551
7552            if (persistChanged) {
7553                schedulePersistUriGrants();
7554            }
7555        }
7556    }
7557
7558    /**
7559     * Prune any older {@link UriPermission} for the given UID until outstanding
7560     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7561     *
7562     * @return if any mutations occured that require persisting.
7563     */
7564    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7565        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7566        if (perms == null) return false;
7567        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7568
7569        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7570        for (UriPermission perm : perms.values()) {
7571            if (perm.persistedModeFlags != 0) {
7572                persisted.add(perm);
7573            }
7574        }
7575
7576        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7577        if (trimCount <= 0) return false;
7578
7579        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7580        for (int i = 0; i < trimCount; i++) {
7581            final UriPermission perm = persisted.get(i);
7582
7583            if (DEBUG_URI_PERMISSION) {
7584                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7585            }
7586
7587            perm.releasePersistableModes(~0);
7588            removeUriPermissionIfNeededLocked(perm);
7589        }
7590
7591        return true;
7592    }
7593
7594    @Override
7595    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7596            String packageName, boolean incoming) {
7597        enforceNotIsolatedCaller("getPersistedUriPermissions");
7598        Preconditions.checkNotNull(packageName, "packageName");
7599
7600        final int callingUid = Binder.getCallingUid();
7601        final IPackageManager pm = AppGlobals.getPackageManager();
7602        try {
7603            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7604            if (packageUid != callingUid) {
7605                throw new SecurityException(
7606                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7607            }
7608        } catch (RemoteException e) {
7609            throw new SecurityException("Failed to verify package name ownership");
7610        }
7611
7612        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7613        synchronized (this) {
7614            if (incoming) {
7615                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7616                        callingUid);
7617                if (perms == null) {
7618                    Slog.w(TAG, "No permission grants found for " + packageName);
7619                } else {
7620                    for (UriPermission perm : perms.values()) {
7621                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7622                            result.add(perm.buildPersistedPublicApiObject());
7623                        }
7624                    }
7625                }
7626            } else {
7627                final int size = mGrantedUriPermissions.size();
7628                for (int i = 0; i < size; i++) {
7629                    final ArrayMap<GrantUri, UriPermission> perms =
7630                            mGrantedUriPermissions.valueAt(i);
7631                    for (UriPermission perm : perms.values()) {
7632                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7633                            result.add(perm.buildPersistedPublicApiObject());
7634                        }
7635                    }
7636                }
7637            }
7638        }
7639        return new ParceledListSlice<android.content.UriPermission>(result);
7640    }
7641
7642    @Override
7643    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7644        synchronized (this) {
7645            ProcessRecord app =
7646                who != null ? getRecordForAppLocked(who) : null;
7647            if (app == null) return;
7648
7649            Message msg = Message.obtain();
7650            msg.what = WAIT_FOR_DEBUGGER_MSG;
7651            msg.obj = app;
7652            msg.arg1 = waiting ? 1 : 0;
7653            mHandler.sendMessage(msg);
7654        }
7655    }
7656
7657    @Override
7658    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7659        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7660        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7661        outInfo.availMem = Process.getFreeMemory();
7662        outInfo.totalMem = Process.getTotalMemory();
7663        outInfo.threshold = homeAppMem;
7664        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7665        outInfo.hiddenAppThreshold = cachedAppMem;
7666        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7667                ProcessList.SERVICE_ADJ);
7668        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7669                ProcessList.VISIBLE_APP_ADJ);
7670        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7671                ProcessList.FOREGROUND_APP_ADJ);
7672    }
7673
7674    // =========================================================
7675    // TASK MANAGEMENT
7676    // =========================================================
7677
7678    @Override
7679    public List<IAppTask> getAppTasks(String callingPackage) {
7680        int callingUid = Binder.getCallingUid();
7681        long ident = Binder.clearCallingIdentity();
7682
7683        synchronized(this) {
7684            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7685            try {
7686                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
7687
7688                final int N = mRecentTasks.size();
7689                for (int i = 0; i < N; i++) {
7690                    TaskRecord tr = mRecentTasks.get(i);
7691                    // Skip tasks that do not match the caller.  We don't need to verify
7692                    // callingPackage, because we are also limiting to callingUid and know
7693                    // that will limit to the correct security sandbox.
7694                    if (tr.effectiveUid != callingUid) {
7695                        continue;
7696                    }
7697                    Intent intent = tr.getBaseIntent();
7698                    if (intent == null ||
7699                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7700                        continue;
7701                    }
7702                    ActivityManager.RecentTaskInfo taskInfo =
7703                            createRecentTaskInfoFromTaskRecord(tr);
7704                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7705                    list.add(taskImpl);
7706                }
7707            } finally {
7708                Binder.restoreCallingIdentity(ident);
7709            }
7710            return list;
7711        }
7712    }
7713
7714    @Override
7715    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7716        final int callingUid = Binder.getCallingUid();
7717        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7718
7719        synchronized(this) {
7720            if (DEBUG_ALL) Slog.v(
7721                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7722
7723            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
7724                    callingUid);
7725
7726            // TODO: Improve with MRU list from all ActivityStacks.
7727            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7728        }
7729
7730        return list;
7731    }
7732
7733    /**
7734     * Creates a new RecentTaskInfo from a TaskRecord.
7735     */
7736    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7737        // Update the task description to reflect any changes in the task stack
7738        tr.updateTaskDescription();
7739
7740        // Compose the recent task info
7741        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7742        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
7743        rti.persistentId = tr.taskId;
7744        rti.baseIntent = new Intent(tr.getBaseIntent());
7745        rti.origActivity = tr.origActivity;
7746        rti.description = tr.lastDescription;
7747        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7748        rti.userId = tr.userId;
7749        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7750        rti.firstActiveTime = tr.firstActiveTime;
7751        rti.lastActiveTime = tr.lastActiveTime;
7752        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7753        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7754        return rti;
7755    }
7756
7757    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
7758        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
7759                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
7760        if (!allowed) {
7761            if (checkPermission(android.Manifest.permission.GET_TASKS,
7762                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
7763                // Temporary compatibility: some existing apps on the system image may
7764                // still be requesting the old permission and not switched to the new
7765                // one; if so, we'll still allow them full access.  This means we need
7766                // to see if they are holding the old permission and are a system app.
7767                try {
7768                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
7769                        allowed = true;
7770                        Slog.w(TAG, caller + ": caller " + callingUid
7771                                + " is using old GET_TASKS but privileged; allowing");
7772                    }
7773                } catch (RemoteException e) {
7774                }
7775            }
7776        }
7777        if (!allowed) {
7778            Slog.w(TAG, caller + ": caller " + callingUid
7779                    + " does not hold GET_TASKS; limiting output");
7780        }
7781        return allowed;
7782    }
7783
7784    @Override
7785    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7786        final int callingUid = Binder.getCallingUid();
7787        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7788                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7789
7790        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7791        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7792        synchronized (this) {
7793            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
7794                    callingUid);
7795            final boolean detailed = checkCallingPermission(
7796                    android.Manifest.permission.GET_DETAILED_TASKS)
7797                    == PackageManager.PERMISSION_GRANTED;
7798
7799            final int recentsCount = mRecentTasks.size();
7800            ArrayList<ActivityManager.RecentTaskInfo> res =
7801                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
7802
7803            final Set<Integer> includedUsers;
7804            if (includeProfiles) {
7805                includedUsers = getProfileIdsLocked(userId);
7806            } else {
7807                includedUsers = new HashSet<>();
7808            }
7809            includedUsers.add(Integer.valueOf(userId));
7810
7811            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
7812                TaskRecord tr = mRecentTasks.get(i);
7813                // Only add calling user or related users recent tasks
7814                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
7815                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
7816                    continue;
7817                }
7818
7819                // Return the entry if desired by the caller.  We always return
7820                // the first entry, because callers always expect this to be the
7821                // foreground app.  We may filter others if the caller has
7822                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7823                // we should exclude the entry.
7824
7825                if (i == 0
7826                        || withExcluded
7827                        || (tr.intent == null)
7828                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7829                                == 0)) {
7830                    if (!allowed) {
7831                        // If the caller doesn't have the GET_TASKS permission, then only
7832                        // allow them to see a small subset of tasks -- their own and home.
7833                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
7834                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
7835                            continue;
7836                        }
7837                    }
7838                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
7839                        if (tr.stack != null && tr.stack.isHomeStack()) {
7840                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
7841                            continue;
7842                        }
7843                    }
7844                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7845                        // Don't include auto remove tasks that are finished or finishing.
7846                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
7847                                + tr);
7848                        continue;
7849                    }
7850                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
7851                            && !tr.isAvailable) {
7852                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
7853                        continue;
7854                    }
7855
7856                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7857                    if (!detailed) {
7858                        rti.baseIntent.replaceExtras((Bundle)null);
7859                    }
7860
7861                    res.add(rti);
7862                    maxNum--;
7863                }
7864            }
7865            return res;
7866        }
7867    }
7868
7869    @Override
7870    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7871        synchronized (this) {
7872            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7873                    "getTaskThumbnail()");
7874            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
7875            if (tr != null) {
7876                return tr.getTaskThumbnailLocked();
7877            }
7878        }
7879        return null;
7880    }
7881
7882    @Override
7883    public int addAppTask(IBinder activityToken, Intent intent,
7884            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
7885        final int callingUid = Binder.getCallingUid();
7886        final long callingIdent = Binder.clearCallingIdentity();
7887
7888        try {
7889            synchronized (this) {
7890                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
7891                if (r == null) {
7892                    throw new IllegalArgumentException("Activity does not exist; token="
7893                            + activityToken);
7894                }
7895                ComponentName comp = intent.getComponent();
7896                if (comp == null) {
7897                    throw new IllegalArgumentException("Intent " + intent
7898                            + " must specify explicit component");
7899                }
7900                if (thumbnail.getWidth() != mThumbnailWidth
7901                        || thumbnail.getHeight() != mThumbnailHeight) {
7902                    throw new IllegalArgumentException("Bad thumbnail size: got "
7903                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
7904                            + mThumbnailWidth + "x" + mThumbnailHeight);
7905                }
7906                if (intent.getSelector() != null) {
7907                    intent.setSelector(null);
7908                }
7909                if (intent.getSourceBounds() != null) {
7910                    intent.setSourceBounds(null);
7911                }
7912                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
7913                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
7914                        // The caller has added this as an auto-remove task...  that makes no
7915                        // sense, so turn off auto-remove.
7916                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
7917                    }
7918                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
7919                    // Must be a new task.
7920                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7921                }
7922                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
7923                    mLastAddedTaskActivity = null;
7924                }
7925                ActivityInfo ainfo = mLastAddedTaskActivity;
7926                if (ainfo == null) {
7927                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
7928                            comp, 0, UserHandle.getUserId(callingUid));
7929                    if (ainfo.applicationInfo.uid != callingUid) {
7930                        throw new SecurityException(
7931                                "Can't add task for another application: target uid="
7932                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
7933                    }
7934                }
7935
7936                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
7937                        intent, description);
7938
7939                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
7940                if (trimIdx >= 0) {
7941                    // If this would have caused a trim, then we'll abort because that
7942                    // means it would be added at the end of the list but then just removed.
7943                    return INVALID_TASK_ID;
7944                }
7945
7946                final int N = mRecentTasks.size();
7947                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
7948                    final TaskRecord tr = mRecentTasks.remove(N - 1);
7949                    tr.removedFromRecents();
7950                }
7951
7952                task.inRecents = true;
7953                mRecentTasks.add(task);
7954                r.task.stack.addTask(task, false, false);
7955
7956                task.setLastThumbnail(thumbnail);
7957                task.freeLastThumbnail();
7958
7959                return task.taskId;
7960            }
7961        } finally {
7962            Binder.restoreCallingIdentity(callingIdent);
7963        }
7964    }
7965
7966    @Override
7967    public Point getAppTaskThumbnailSize() {
7968        synchronized (this) {
7969            return new Point(mThumbnailWidth,  mThumbnailHeight);
7970        }
7971    }
7972
7973    @Override
7974    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7975        synchronized (this) {
7976            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7977            if (r != null) {
7978                r.setTaskDescription(td);
7979                r.task.updateTaskDescription();
7980            }
7981        }
7982    }
7983
7984    @Override
7985    public void setTaskResizeable(int taskId, boolean resizeable) {
7986        synchronized (this) {
7987            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
7988            if (task == null) {
7989                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
7990                return;
7991            }
7992            if (task.mResizeable != resizeable) {
7993                task.mResizeable = resizeable;
7994                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
7995                mStackSupervisor.resumeTopActivitiesLocked();
7996            }
7997        }
7998    }
7999
8000    @Override
8001    public void resizeTask(int taskId, Rect bounds) {
8002        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8003                "resizeTask()");
8004        long ident = Binder.clearCallingIdentity();
8005        try {
8006            synchronized (this) {
8007                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8008                if (task == null) {
8009                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8010                    return;
8011                }
8012                mStackSupervisor.resizeTaskLocked(task, bounds);
8013            }
8014        } finally {
8015            Binder.restoreCallingIdentity(ident);
8016        }
8017    }
8018
8019    @Override
8020    public Bitmap getTaskDescriptionIcon(String filename) {
8021        if (!FileUtils.isValidExtFilename(filename)
8022                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8023            throw new IllegalArgumentException("Bad filename: " + filename);
8024        }
8025        return mTaskPersister.getTaskDescriptionIcon(filename);
8026    }
8027
8028    @Override
8029    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8030            throws RemoteException {
8031        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8032                opts.getCustomInPlaceResId() == 0) {
8033            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8034                    "with valid animation");
8035        }
8036        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8037        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8038                opts.getCustomInPlaceResId());
8039        mWindowManager.executeAppTransition();
8040    }
8041
8042    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8043        mRecentTasks.remove(tr);
8044        tr.removedFromRecents();
8045        ComponentName component = tr.getBaseIntent().getComponent();
8046        if (component == null) {
8047            Slog.w(TAG, "No component for base intent of task: " + tr);
8048            return;
8049        }
8050
8051        if (!killProcess) {
8052            return;
8053        }
8054
8055        // Determine if the process(es) for this task should be killed.
8056        final String pkg = component.getPackageName();
8057        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8058        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8059        for (int i = 0; i < pmap.size(); i++) {
8060
8061            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8062            for (int j = 0; j < uids.size(); j++) {
8063                ProcessRecord proc = uids.valueAt(j);
8064                if (proc.userId != tr.userId) {
8065                    // Don't kill process for a different user.
8066                    continue;
8067                }
8068                if (proc == mHomeProcess) {
8069                    // Don't kill the home process along with tasks from the same package.
8070                    continue;
8071                }
8072                if (!proc.pkgList.containsKey(pkg)) {
8073                    // Don't kill process that is not associated with this task.
8074                    continue;
8075                }
8076
8077                for (int k = 0; k < proc.activities.size(); k++) {
8078                    TaskRecord otherTask = proc.activities.get(k).task;
8079                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8080                        // Don't kill process(es) that has an activity in a different task that is
8081                        // also in recents.
8082                        return;
8083                    }
8084                }
8085
8086                // Add process to kill list.
8087                procsToKill.add(proc);
8088            }
8089        }
8090
8091        // Find any running services associated with this app and stop if needed.
8092        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8093
8094        // Kill the running processes.
8095        for (int i = 0; i < procsToKill.size(); i++) {
8096            ProcessRecord pr = procsToKill.get(i);
8097            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8098                pr.kill("remove task", true);
8099            } else {
8100                pr.waitingToKill = "remove task";
8101            }
8102        }
8103    }
8104
8105    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8106        // Remove all tasks with activities in the specified package from the list of recent tasks
8107        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8108            TaskRecord tr = mRecentTasks.get(i);
8109            if (tr.userId != userId) continue;
8110
8111            ComponentName cn = tr.intent.getComponent();
8112            if (cn != null && cn.getPackageName().equals(packageName)) {
8113                // If the package name matches, remove the task.
8114                removeTaskByIdLocked(tr.taskId, true);
8115            }
8116        }
8117    }
8118
8119    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8120        final IPackageManager pm = AppGlobals.getPackageManager();
8121        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8122
8123        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8124            TaskRecord tr = mRecentTasks.get(i);
8125            if (tr.userId != userId) continue;
8126
8127            ComponentName cn = tr.intent.getComponent();
8128            if (cn != null && cn.getPackageName().equals(packageName)) {
8129                // Skip if component still exists in the package.
8130                if (componentsKnownToExist.contains(cn)) continue;
8131
8132                try {
8133                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8134                    if (info != null) {
8135                        componentsKnownToExist.add(cn);
8136                    } else {
8137                        removeTaskByIdLocked(tr.taskId, false);
8138                    }
8139                } catch (RemoteException e) {
8140                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8141                }
8142            }
8143        }
8144    }
8145
8146    /**
8147     * Removes the task with the specified task id.
8148     *
8149     * @param taskId Identifier of the task to be removed.
8150     * @param killProcess Kill any process associated with the task if possible.
8151     * @return Returns true if the given task was found and removed.
8152     */
8153    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8154        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8155        if (tr != null) {
8156            tr.removeTaskActivitiesLocked();
8157            cleanUpRemovedTaskLocked(tr, killProcess);
8158            if (tr.isPersistable) {
8159                notifyTaskPersisterLocked(null, true);
8160            }
8161            return true;
8162        }
8163        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8164        return false;
8165    }
8166
8167    @Override
8168    public boolean removeTask(int taskId) {
8169        synchronized (this) {
8170            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8171                    "removeTask()");
8172            long ident = Binder.clearCallingIdentity();
8173            try {
8174                return removeTaskByIdLocked(taskId, true);
8175            } finally {
8176                Binder.restoreCallingIdentity(ident);
8177            }
8178        }
8179    }
8180
8181    /**
8182     * TODO: Add mController hook
8183     */
8184    @Override
8185    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8186        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8187                "moveTaskToFront()");
8188
8189        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8190        synchronized(this) {
8191            moveTaskToFrontLocked(taskId, flags, options);
8192        }
8193    }
8194
8195    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8196        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8197                Binder.getCallingUid(), -1, -1, "Task to front")) {
8198            ActivityOptions.abort(options);
8199            return;
8200        }
8201        final long origId = Binder.clearCallingIdentity();
8202        try {
8203            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8204            if (task == null) {
8205                Slog.d(TAG, "Could not find task for id: "+ taskId);
8206                return;
8207            }
8208            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8209                mStackSupervisor.showLockTaskToast();
8210                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8211                return;
8212            }
8213            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8214            if (prev != null && prev.isRecentsActivity()) {
8215                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8216            }
8217            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8218        } finally {
8219            Binder.restoreCallingIdentity(origId);
8220        }
8221        ActivityOptions.abort(options);
8222    }
8223
8224    /**
8225     * Moves an activity, and all of the other activities within the same task, to the bottom
8226     * of the history stack.  The activity's order within the task is unchanged.
8227     *
8228     * @param token A reference to the activity we wish to move
8229     * @param nonRoot If false then this only works if the activity is the root
8230     *                of a task; if true it will work for any activity in a task.
8231     * @return Returns true if the move completed, false if not.
8232     */
8233    @Override
8234    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8235        enforceNotIsolatedCaller("moveActivityTaskToBack");
8236        synchronized(this) {
8237            final long origId = Binder.clearCallingIdentity();
8238            try {
8239                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8240                if (taskId >= 0) {
8241                    if ((mStackSupervisor.mLockTaskModeTask != null)
8242                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8243                        mStackSupervisor.showLockTaskToast();
8244                        return false;
8245                    }
8246                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8247                }
8248            } finally {
8249                Binder.restoreCallingIdentity(origId);
8250            }
8251        }
8252        return false;
8253    }
8254
8255    @Override
8256    public void moveTaskBackwards(int task) {
8257        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8258                "moveTaskBackwards()");
8259
8260        synchronized(this) {
8261            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8262                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8263                return;
8264            }
8265            final long origId = Binder.clearCallingIdentity();
8266            moveTaskBackwardsLocked(task);
8267            Binder.restoreCallingIdentity(origId);
8268        }
8269    }
8270
8271    private final void moveTaskBackwardsLocked(int task) {
8272        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8273    }
8274
8275    @Override
8276    public IBinder getHomeActivityToken() throws RemoteException {
8277        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8278                "getHomeActivityToken()");
8279        synchronized (this) {
8280            return mStackSupervisor.getHomeActivityToken();
8281        }
8282    }
8283
8284    @Override
8285    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8286            IActivityContainerCallback callback) throws RemoteException {
8287        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8288                "createActivityContainer()");
8289        synchronized (this) {
8290            if (parentActivityToken == null) {
8291                throw new IllegalArgumentException("parent token must not be null");
8292            }
8293            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8294            if (r == null) {
8295                return null;
8296            }
8297            if (callback == null) {
8298                throw new IllegalArgumentException("callback must not be null");
8299            }
8300            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8301        }
8302    }
8303
8304    @Override
8305    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8306        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8307                "deleteActivityContainer()");
8308        synchronized (this) {
8309            mStackSupervisor.deleteActivityContainer(container);
8310        }
8311    }
8312
8313    @Override
8314    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8315        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8316                "createStackOnDisplay()");
8317        synchronized (this) {
8318            final int stackId = mStackSupervisor.getNextStackId();
8319            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8320            if (stack == null) {
8321                return null;
8322            }
8323            return stack.mActivityContainer;
8324        }
8325    }
8326
8327    @Override
8328    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8329        synchronized (this) {
8330            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8331            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8332                return stack.mActivityContainer.getDisplayId();
8333            }
8334            return Display.DEFAULT_DISPLAY;
8335        }
8336    }
8337
8338    @Override
8339    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8340        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8341                "moveTaskToStack()");
8342        if (stackId == HOME_STACK_ID) {
8343            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8344                    new RuntimeException("here").fillInStackTrace());
8345        }
8346        synchronized (this) {
8347            long ident = Binder.clearCallingIdentity();
8348            try {
8349                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8350                        + stackId + " toTop=" + toTop);
8351                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8352            } finally {
8353                Binder.restoreCallingIdentity(ident);
8354            }
8355        }
8356    }
8357
8358    @Override
8359    public void resizeStack(int stackId, Rect bounds) {
8360        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8361                "resizeStack()");
8362        long ident = Binder.clearCallingIdentity();
8363        try {
8364            synchronized (this) {
8365                mStackSupervisor.resizeStackLocked(stackId, bounds);
8366            }
8367        } finally {
8368            Binder.restoreCallingIdentity(ident);
8369        }
8370    }
8371
8372    @Override
8373    public List<StackInfo> getAllStackInfos() {
8374        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8375                "getAllStackInfos()");
8376        long ident = Binder.clearCallingIdentity();
8377        try {
8378            synchronized (this) {
8379                return mStackSupervisor.getAllStackInfosLocked();
8380            }
8381        } finally {
8382            Binder.restoreCallingIdentity(ident);
8383        }
8384    }
8385
8386    @Override
8387    public StackInfo getStackInfo(int stackId) {
8388        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8389                "getStackInfo()");
8390        long ident = Binder.clearCallingIdentity();
8391        try {
8392            synchronized (this) {
8393                return mStackSupervisor.getStackInfoLocked(stackId);
8394            }
8395        } finally {
8396            Binder.restoreCallingIdentity(ident);
8397        }
8398    }
8399
8400    @Override
8401    public boolean isInHomeStack(int taskId) {
8402        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8403                "getStackInfo()");
8404        long ident = Binder.clearCallingIdentity();
8405        try {
8406            synchronized (this) {
8407                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8408                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8409            }
8410        } finally {
8411            Binder.restoreCallingIdentity(ident);
8412        }
8413    }
8414
8415    @Override
8416    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8417        synchronized(this) {
8418            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8419        }
8420    }
8421
8422    private boolean isLockTaskAuthorized(String pkg) {
8423        final DevicePolicyManager dpm = (DevicePolicyManager)
8424                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8425        try {
8426            int uid = mContext.getPackageManager().getPackageUid(pkg,
8427                    Binder.getCallingUserHandle().getIdentifier());
8428            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8429        } catch (NameNotFoundException e) {
8430            return false;
8431        }
8432    }
8433
8434    void startLockTaskMode(TaskRecord task) {
8435        final String pkg;
8436        synchronized (this) {
8437            pkg = task.intent.getComponent().getPackageName();
8438        }
8439        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
8440        // is initiated by system after the pinning request was shown and locked mode is initiated
8441        // by an authorized app directly
8442        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8443        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8444            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8445                    StatusBarManagerInternal.class);
8446            if (statusBarManager != null) {
8447                statusBarManager.showScreenPinningRequest();
8448            }
8449            return;
8450        }
8451        long ident = Binder.clearCallingIdentity();
8452        try {
8453            synchronized (this) {
8454                // Since we lost lock on task, make sure it is still there.
8455                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8456                if (task != null) {
8457                    if (!isSystemInitiated
8458                            && ((mStackSupervisor.getFocusedStack() == null)
8459                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8460                        throw new IllegalArgumentException("Invalid task, not in foreground");
8461                    }
8462                    mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
8463                            ActivityManager.LOCK_TASK_MODE_PINNED :
8464                            ActivityManager.LOCK_TASK_MODE_LOCKED,
8465                            "startLockTask");
8466                }
8467            }
8468        } finally {
8469            Binder.restoreCallingIdentity(ident);
8470        }
8471    }
8472
8473    @Override
8474    public void startLockTaskMode(int taskId) {
8475        final TaskRecord task;
8476        long ident = Binder.clearCallingIdentity();
8477        try {
8478            synchronized (this) {
8479                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8480            }
8481        } finally {
8482            Binder.restoreCallingIdentity(ident);
8483        }
8484        if (task != null) {
8485            startLockTaskMode(task);
8486        }
8487    }
8488
8489    @Override
8490    public void startLockTaskMode(IBinder token) {
8491        final TaskRecord task;
8492        long ident = Binder.clearCallingIdentity();
8493        try {
8494            synchronized (this) {
8495                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8496                if (r == null) {
8497                    return;
8498                }
8499                task = r.task;
8500            }
8501        } finally {
8502            Binder.restoreCallingIdentity(ident);
8503        }
8504        if (task != null) {
8505            startLockTaskMode(task);
8506        }
8507    }
8508
8509    @Override
8510    public void startLockTaskModeOnCurrent() throws RemoteException {
8511        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8512                "startLockTaskModeOnCurrent");
8513        long ident = Binder.clearCallingIdentity();
8514        try {
8515            ActivityRecord r = null;
8516            synchronized (this) {
8517                r = mStackSupervisor.topRunningActivityLocked();
8518            }
8519            startLockTaskMode(r.task);
8520        } finally {
8521            Binder.restoreCallingIdentity(ident);
8522        }
8523    }
8524
8525    @Override
8526    public void stopLockTaskMode() {
8527        // Verify that the user matches the package of the intent for the TaskRecord
8528        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8529        // and stopLockTaskMode.
8530        final int callingUid = Binder.getCallingUid();
8531        if (callingUid != Process.SYSTEM_UID) {
8532            try {
8533                String pkg =
8534                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8535                int uid = mContext.getPackageManager().getPackageUid(pkg,
8536                        Binder.getCallingUserHandle().getIdentifier());
8537                if (uid != callingUid) {
8538                    throw new SecurityException("Invalid uid, expected " + uid);
8539                }
8540            } catch (NameNotFoundException e) {
8541                Log.d(TAG, "stopLockTaskMode " + e);
8542                return;
8543            }
8544        }
8545        long ident = Binder.clearCallingIdentity();
8546        try {
8547            Log.d(TAG, "stopLockTaskMode");
8548            // Stop lock task
8549            synchronized (this) {
8550                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
8551                        "stopLockTask");
8552            }
8553        } finally {
8554            Binder.restoreCallingIdentity(ident);
8555        }
8556    }
8557
8558    @Override
8559    public void stopLockTaskModeOnCurrent() throws RemoteException {
8560        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8561                "stopLockTaskModeOnCurrent");
8562        long ident = Binder.clearCallingIdentity();
8563        try {
8564            stopLockTaskMode();
8565        } finally {
8566            Binder.restoreCallingIdentity(ident);
8567        }
8568    }
8569
8570    @Override
8571    public boolean isInLockTaskMode() {
8572        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
8573    }
8574
8575    @Override
8576    public int getLockTaskModeState() {
8577        synchronized (this) {
8578            return mStackSupervisor.getLockTaskModeState();
8579        }
8580    }
8581
8582    // =========================================================
8583    // CONTENT PROVIDERS
8584    // =========================================================
8585
8586    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8587        List<ProviderInfo> providers = null;
8588        try {
8589            providers = AppGlobals.getPackageManager().
8590                queryContentProviders(app.processName, app.uid,
8591                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8592        } catch (RemoteException ex) {
8593        }
8594        if (DEBUG_MU)
8595            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8596        int userId = app.userId;
8597        if (providers != null) {
8598            int N = providers.size();
8599            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8600            for (int i=0; i<N; i++) {
8601                ProviderInfo cpi =
8602                    (ProviderInfo)providers.get(i);
8603                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8604                        cpi.name, cpi.flags);
8605                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8606                    // This is a singleton provider, but a user besides the
8607                    // default user is asking to initialize a process it runs
8608                    // in...  well, no, it doesn't actually run in this process,
8609                    // it runs in the process of the default user.  Get rid of it.
8610                    providers.remove(i);
8611                    N--;
8612                    i--;
8613                    continue;
8614                }
8615
8616                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8617                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8618                if (cpr == null) {
8619                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8620                    mProviderMap.putProviderByClass(comp, cpr);
8621                }
8622                if (DEBUG_MU)
8623                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8624                app.pubProviders.put(cpi.name, cpr);
8625                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8626                    // Don't add this if it is a platform component that is marked
8627                    // to run in multiple processes, because this is actually
8628                    // part of the framework so doesn't make sense to track as a
8629                    // separate apk in the process.
8630                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8631                            mProcessStats);
8632                }
8633                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8634            }
8635        }
8636        return providers;
8637    }
8638
8639    /**
8640     * Check if {@link ProcessRecord} has a possible chance at accessing the
8641     * given {@link ProviderInfo}. Final permission checking is always done
8642     * in {@link ContentProvider}.
8643     */
8644    private final String checkContentProviderPermissionLocked(
8645            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8646        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8647        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8648        boolean checkedGrants = false;
8649        if (checkUser) {
8650            // Looking for cross-user grants before enforcing the typical cross-users permissions
8651            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8652            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8653                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8654                    return null;
8655                }
8656                checkedGrants = true;
8657            }
8658            userId = handleIncomingUser(callingPid, callingUid, userId,
8659                    false, ALLOW_NON_FULL,
8660                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8661            if (userId != tmpTargetUserId) {
8662                // When we actually went to determine the final targer user ID, this ended
8663                // up different than our initial check for the authority.  This is because
8664                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8665                // SELF.  So we need to re-check the grants again.
8666                checkedGrants = false;
8667            }
8668        }
8669        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8670                cpi.applicationInfo.uid, cpi.exported)
8671                == PackageManager.PERMISSION_GRANTED) {
8672            return null;
8673        }
8674        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8675                cpi.applicationInfo.uid, cpi.exported)
8676                == PackageManager.PERMISSION_GRANTED) {
8677            return null;
8678        }
8679
8680        PathPermission[] pps = cpi.pathPermissions;
8681        if (pps != null) {
8682            int i = pps.length;
8683            while (i > 0) {
8684                i--;
8685                PathPermission pp = pps[i];
8686                String pprperm = pp.getReadPermission();
8687                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8688                        cpi.applicationInfo.uid, cpi.exported)
8689                        == PackageManager.PERMISSION_GRANTED) {
8690                    return null;
8691                }
8692                String ppwperm = pp.getWritePermission();
8693                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8694                        cpi.applicationInfo.uid, cpi.exported)
8695                        == PackageManager.PERMISSION_GRANTED) {
8696                    return null;
8697                }
8698            }
8699        }
8700        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8701            return null;
8702        }
8703
8704        String msg;
8705        if (!cpi.exported) {
8706            msg = "Permission Denial: opening provider " + cpi.name
8707                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8708                    + ", uid=" + callingUid + ") that is not exported from uid "
8709                    + cpi.applicationInfo.uid;
8710        } else {
8711            msg = "Permission Denial: opening provider " + cpi.name
8712                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8713                    + ", uid=" + callingUid + ") requires "
8714                    + cpi.readPermission + " or " + cpi.writePermission;
8715        }
8716        Slog.w(TAG, msg);
8717        return msg;
8718    }
8719
8720    /**
8721     * Returns if the ContentProvider has granted a uri to callingUid
8722     */
8723    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8724        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8725        if (perms != null) {
8726            for (int i=perms.size()-1; i>=0; i--) {
8727                GrantUri grantUri = perms.keyAt(i);
8728                if (grantUri.sourceUserId == userId || !checkUser) {
8729                    if (matchesProvider(grantUri.uri, cpi)) {
8730                        return true;
8731                    }
8732                }
8733            }
8734        }
8735        return false;
8736    }
8737
8738    /**
8739     * Returns true if the uri authority is one of the authorities specified in the provider.
8740     */
8741    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8742        String uriAuth = uri.getAuthority();
8743        String cpiAuth = cpi.authority;
8744        if (cpiAuth.indexOf(';') == -1) {
8745            return cpiAuth.equals(uriAuth);
8746        }
8747        String[] cpiAuths = cpiAuth.split(";");
8748        int length = cpiAuths.length;
8749        for (int i = 0; i < length; i++) {
8750            if (cpiAuths[i].equals(uriAuth)) return true;
8751        }
8752        return false;
8753    }
8754
8755    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8756            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8757        if (r != null) {
8758            for (int i=0; i<r.conProviders.size(); i++) {
8759                ContentProviderConnection conn = r.conProviders.get(i);
8760                if (conn.provider == cpr) {
8761                    if (DEBUG_PROVIDER) Slog.v(TAG,
8762                            "Adding provider requested by "
8763                            + r.processName + " from process "
8764                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8765                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8766                    if (stable) {
8767                        conn.stableCount++;
8768                        conn.numStableIncs++;
8769                    } else {
8770                        conn.unstableCount++;
8771                        conn.numUnstableIncs++;
8772                    }
8773                    return conn;
8774                }
8775            }
8776            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8777            if (stable) {
8778                conn.stableCount = 1;
8779                conn.numStableIncs = 1;
8780            } else {
8781                conn.unstableCount = 1;
8782                conn.numUnstableIncs = 1;
8783            }
8784            cpr.connections.add(conn);
8785            r.conProviders.add(conn);
8786            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
8787            return conn;
8788        }
8789        cpr.addExternalProcessHandleLocked(externalProcessToken);
8790        return null;
8791    }
8792
8793    boolean decProviderCountLocked(ContentProviderConnection conn,
8794            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8795        if (conn != null) {
8796            cpr = conn.provider;
8797            if (DEBUG_PROVIDER) Slog.v(TAG,
8798                    "Removing provider requested by "
8799                    + conn.client.processName + " from process "
8800                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8801                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8802            if (stable) {
8803                conn.stableCount--;
8804            } else {
8805                conn.unstableCount--;
8806            }
8807            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8808                cpr.connections.remove(conn);
8809                conn.client.conProviders.remove(conn);
8810                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
8811                return true;
8812            }
8813            return false;
8814        }
8815        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8816        return false;
8817    }
8818
8819    private void checkTime(long startTime, String where) {
8820        long now = SystemClock.elapsedRealtime();
8821        if ((now-startTime) > 1000) {
8822            // If we are taking more than a second, log about it.
8823            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
8824        }
8825    }
8826
8827    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8828            String name, IBinder token, boolean stable, int userId) {
8829        ContentProviderRecord cpr;
8830        ContentProviderConnection conn = null;
8831        ProviderInfo cpi = null;
8832
8833        synchronized(this) {
8834            long startTime = SystemClock.elapsedRealtime();
8835
8836            ProcessRecord r = null;
8837            if (caller != null) {
8838                r = getRecordForAppLocked(caller);
8839                if (r == null) {
8840                    throw new SecurityException(
8841                            "Unable to find app for caller " + caller
8842                          + " (pid=" + Binder.getCallingPid()
8843                          + ") when getting content provider " + name);
8844                }
8845            }
8846
8847            boolean checkCrossUser = true;
8848
8849            checkTime(startTime, "getContentProviderImpl: getProviderByName");
8850
8851            // First check if this content provider has been published...
8852            cpr = mProviderMap.getProviderByName(name, userId);
8853            // If that didn't work, check if it exists for user 0 and then
8854            // verify that it's a singleton provider before using it.
8855            if (cpr == null && userId != UserHandle.USER_OWNER) {
8856                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8857                if (cpr != null) {
8858                    cpi = cpr.info;
8859                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8860                            cpi.name, cpi.flags)
8861                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8862                        userId = UserHandle.USER_OWNER;
8863                        checkCrossUser = false;
8864                    } else {
8865                        cpr = null;
8866                        cpi = null;
8867                    }
8868                }
8869            }
8870
8871            boolean providerRunning = cpr != null;
8872            if (providerRunning) {
8873                cpi = cpr.info;
8874                String msg;
8875                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
8876                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8877                        != null) {
8878                    throw new SecurityException(msg);
8879                }
8880                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
8881
8882                if (r != null && cpr.canRunHere(r)) {
8883                    // This provider has been published or is in the process
8884                    // of being published...  but it is also allowed to run
8885                    // in the caller's process, so don't make a connection
8886                    // and just let the caller instantiate its own instance.
8887                    ContentProviderHolder holder = cpr.newHolder(null);
8888                    // don't give caller the provider object, it needs
8889                    // to make its own.
8890                    holder.provider = null;
8891                    return holder;
8892                }
8893
8894                final long origId = Binder.clearCallingIdentity();
8895
8896                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
8897
8898                // In this case the provider instance already exists, so we can
8899                // return it right away.
8900                conn = incProviderCountLocked(r, cpr, token, stable);
8901                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8902                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8903                        // If this is a perceptible app accessing the provider,
8904                        // make sure to count it as being accessed and thus
8905                        // back up on the LRU list.  This is good because
8906                        // content providers are often expensive to start.
8907                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
8908                        updateLruProcessLocked(cpr.proc, false, null);
8909                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
8910                    }
8911                }
8912
8913                if (cpr.proc != null) {
8914                    if (false) {
8915                        if (cpr.name.flattenToShortString().equals(
8916                                "com.android.providers.calendar/.CalendarProvider2")) {
8917                            Slog.v(TAG, "****************** KILLING "
8918                                + cpr.name.flattenToShortString());
8919                            Process.killProcess(cpr.proc.pid);
8920                        }
8921                    }
8922                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
8923                    boolean success = updateOomAdjLocked(cpr.proc);
8924                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
8925                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8926                    // NOTE: there is still a race here where a signal could be
8927                    // pending on the process even though we managed to update its
8928                    // adj level.  Not sure what to do about this, but at least
8929                    // the race is now smaller.
8930                    if (!success) {
8931                        // Uh oh...  it looks like the provider's process
8932                        // has been killed on us.  We need to wait for a new
8933                        // process to be started, and make sure its death
8934                        // doesn't kill our process.
8935                        Slog.i(TAG,
8936                                "Existing provider " + cpr.name.flattenToShortString()
8937                                + " is crashing; detaching " + r);
8938                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8939                        checkTime(startTime, "getContentProviderImpl: before appDied");
8940                        appDiedLocked(cpr.proc);
8941                        checkTime(startTime, "getContentProviderImpl: after appDied");
8942                        if (!lastRef) {
8943                            // This wasn't the last ref our process had on
8944                            // the provider...  we have now been killed, bail.
8945                            return null;
8946                        }
8947                        providerRunning = false;
8948                        conn = null;
8949                    }
8950                }
8951
8952                Binder.restoreCallingIdentity(origId);
8953            }
8954
8955            boolean singleton;
8956            if (!providerRunning) {
8957                try {
8958                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
8959                    cpi = AppGlobals.getPackageManager().
8960                        resolveContentProvider(name,
8961                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8962                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
8963                } catch (RemoteException ex) {
8964                }
8965                if (cpi == null) {
8966                    return null;
8967                }
8968                // If the provider is a singleton AND
8969                // (it's a call within the same user || the provider is a
8970                // privileged app)
8971                // Then allow connecting to the singleton provider
8972                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8973                        cpi.name, cpi.flags)
8974                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8975                if (singleton) {
8976                    userId = UserHandle.USER_OWNER;
8977                }
8978                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8979                checkTime(startTime, "getContentProviderImpl: got app info for user");
8980
8981                String msg;
8982                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
8983                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8984                        != null) {
8985                    throw new SecurityException(msg);
8986                }
8987                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
8988
8989                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8990                        && !cpi.processName.equals("system")) {
8991                    // If this content provider does not run in the system
8992                    // process, and the system is not yet ready to run other
8993                    // processes, then fail fast instead of hanging.
8994                    throw new IllegalArgumentException(
8995                            "Attempt to launch content provider before system ready");
8996                }
8997
8998                // Make sure that the user who owns this provider is running.  If not,
8999                // we don't want to allow it to run.
9000                if (!isUserRunningLocked(userId, false)) {
9001                    Slog.w(TAG, "Unable to launch app "
9002                            + cpi.applicationInfo.packageName + "/"
9003                            + cpi.applicationInfo.uid + " for provider "
9004                            + name + ": user " + userId + " is stopped");
9005                    return null;
9006                }
9007
9008                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9009                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9010                cpr = mProviderMap.getProviderByClass(comp, userId);
9011                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9012                final boolean firstClass = cpr == null;
9013                if (firstClass) {
9014                    final long ident = Binder.clearCallingIdentity();
9015                    try {
9016                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9017                        ApplicationInfo ai =
9018                            AppGlobals.getPackageManager().
9019                                getApplicationInfo(
9020                                        cpi.applicationInfo.packageName,
9021                                        STOCK_PM_FLAGS, userId);
9022                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9023                        if (ai == null) {
9024                            Slog.w(TAG, "No package info for content provider "
9025                                    + cpi.name);
9026                            return null;
9027                        }
9028                        ai = getAppInfoForUser(ai, userId);
9029                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9030                    } catch (RemoteException ex) {
9031                        // pm is in same process, this will never happen.
9032                    } finally {
9033                        Binder.restoreCallingIdentity(ident);
9034                    }
9035                }
9036
9037                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9038
9039                if (r != null && cpr.canRunHere(r)) {
9040                    // If this is a multiprocess provider, then just return its
9041                    // info and allow the caller to instantiate it.  Only do
9042                    // this if the provider is the same user as the caller's
9043                    // process, or can run as root (so can be in any process).
9044                    return cpr.newHolder(null);
9045                }
9046
9047                if (DEBUG_PROVIDER) {
9048                    RuntimeException e = new RuntimeException("here");
9049                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9050                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9051                }
9052
9053                // This is single process, and our app is now connecting to it.
9054                // See if we are already in the process of launching this
9055                // provider.
9056                final int N = mLaunchingProviders.size();
9057                int i;
9058                for (i=0; i<N; i++) {
9059                    if (mLaunchingProviders.get(i) == cpr) {
9060                        break;
9061                    }
9062                }
9063
9064                // If the provider is not already being launched, then get it
9065                // started.
9066                if (i >= N) {
9067                    final long origId = Binder.clearCallingIdentity();
9068
9069                    try {
9070                        // Content provider is now in use, its package can't be stopped.
9071                        try {
9072                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9073                            AppGlobals.getPackageManager().setPackageStoppedState(
9074                                    cpr.appInfo.packageName, false, userId);
9075                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9076                        } catch (RemoteException e) {
9077                        } catch (IllegalArgumentException e) {
9078                            Slog.w(TAG, "Failed trying to unstop package "
9079                                    + cpr.appInfo.packageName + ": " + e);
9080                        }
9081
9082                        // Use existing process if already started
9083                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9084                        ProcessRecord proc = getProcessRecordLocked(
9085                                cpi.processName, cpr.appInfo.uid, false);
9086                        if (proc != null && proc.thread != null) {
9087                            if (DEBUG_PROVIDER) {
9088                                Slog.d(TAG, "Installing in existing process " + proc);
9089                            }
9090                            if (!proc.pubProviders.containsKey(cpi.name)) {
9091                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9092                                proc.pubProviders.put(cpi.name, cpr);
9093                                try {
9094                                    proc.thread.scheduleInstallProvider(cpi);
9095                                } catch (RemoteException e) {
9096                                }
9097                            }
9098                        } else {
9099                            checkTime(startTime, "getContentProviderImpl: before start process");
9100                            proc = startProcessLocked(cpi.processName,
9101                                    cpr.appInfo, false, 0, "content provider",
9102                                    new ComponentName(cpi.applicationInfo.packageName,
9103                                            cpi.name), false, false, false);
9104                            checkTime(startTime, "getContentProviderImpl: after start process");
9105                            if (proc == null) {
9106                                Slog.w(TAG, "Unable to launch app "
9107                                        + cpi.applicationInfo.packageName + "/"
9108                                        + cpi.applicationInfo.uid + " for provider "
9109                                        + name + ": process is bad");
9110                                return null;
9111                            }
9112                        }
9113                        cpr.launchingApp = proc;
9114                        mLaunchingProviders.add(cpr);
9115                    } finally {
9116                        Binder.restoreCallingIdentity(origId);
9117                    }
9118                }
9119
9120                checkTime(startTime, "getContentProviderImpl: updating data structures");
9121
9122                // Make sure the provider is published (the same provider class
9123                // may be published under multiple names).
9124                if (firstClass) {
9125                    mProviderMap.putProviderByClass(comp, cpr);
9126                }
9127
9128                mProviderMap.putProviderByName(name, cpr);
9129                conn = incProviderCountLocked(r, cpr, token, stable);
9130                if (conn != null) {
9131                    conn.waiting = true;
9132                }
9133            }
9134            checkTime(startTime, "getContentProviderImpl: done!");
9135        }
9136
9137        // Wait for the provider to be published...
9138        synchronized (cpr) {
9139            while (cpr.provider == null) {
9140                if (cpr.launchingApp == null) {
9141                    Slog.w(TAG, "Unable to launch app "
9142                            + cpi.applicationInfo.packageName + "/"
9143                            + cpi.applicationInfo.uid + " for provider "
9144                            + name + ": launching app became null");
9145                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9146                            UserHandle.getUserId(cpi.applicationInfo.uid),
9147                            cpi.applicationInfo.packageName,
9148                            cpi.applicationInfo.uid, name);
9149                    return null;
9150                }
9151                try {
9152                    if (DEBUG_MU) {
9153                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9154                                + cpr.launchingApp);
9155                    }
9156                    if (conn != null) {
9157                        conn.waiting = true;
9158                    }
9159                    cpr.wait();
9160                } catch (InterruptedException ex) {
9161                } finally {
9162                    if (conn != null) {
9163                        conn.waiting = false;
9164                    }
9165                }
9166            }
9167        }
9168        return cpr != null ? cpr.newHolder(conn) : null;
9169    }
9170
9171    @Override
9172    public final ContentProviderHolder getContentProvider(
9173            IApplicationThread caller, String name, int userId, boolean stable) {
9174        enforceNotIsolatedCaller("getContentProvider");
9175        if (caller == null) {
9176            String msg = "null IApplicationThread when getting content provider "
9177                    + name;
9178            Slog.w(TAG, msg);
9179            throw new SecurityException(msg);
9180        }
9181        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9182        // with cross-user grant.
9183        return getContentProviderImpl(caller, name, null, stable, userId);
9184    }
9185
9186    public ContentProviderHolder getContentProviderExternal(
9187            String name, int userId, IBinder token) {
9188        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9189            "Do not have permission in call getContentProviderExternal()");
9190        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9191                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9192        return getContentProviderExternalUnchecked(name, token, userId);
9193    }
9194
9195    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9196            IBinder token, int userId) {
9197        return getContentProviderImpl(null, name, token, true, userId);
9198    }
9199
9200    /**
9201     * Drop a content provider from a ProcessRecord's bookkeeping
9202     */
9203    public void removeContentProvider(IBinder connection, boolean stable) {
9204        enforceNotIsolatedCaller("removeContentProvider");
9205        long ident = Binder.clearCallingIdentity();
9206        try {
9207            synchronized (this) {
9208                ContentProviderConnection conn;
9209                try {
9210                    conn = (ContentProviderConnection)connection;
9211                } catch (ClassCastException e) {
9212                    String msg ="removeContentProvider: " + connection
9213                            + " not a ContentProviderConnection";
9214                    Slog.w(TAG, msg);
9215                    throw new IllegalArgumentException(msg);
9216                }
9217                if (conn == null) {
9218                    throw new NullPointerException("connection is null");
9219                }
9220                if (decProviderCountLocked(conn, null, null, stable)) {
9221                    updateOomAdjLocked();
9222                }
9223            }
9224        } finally {
9225            Binder.restoreCallingIdentity(ident);
9226        }
9227    }
9228
9229    public void removeContentProviderExternal(String name, IBinder token) {
9230        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9231            "Do not have permission in call removeContentProviderExternal()");
9232        int userId = UserHandle.getCallingUserId();
9233        long ident = Binder.clearCallingIdentity();
9234        try {
9235            removeContentProviderExternalUnchecked(name, token, userId);
9236        } finally {
9237            Binder.restoreCallingIdentity(ident);
9238        }
9239    }
9240
9241    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9242        synchronized (this) {
9243            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9244            if(cpr == null) {
9245                //remove from mProvidersByClass
9246                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9247                return;
9248            }
9249
9250            //update content provider record entry info
9251            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9252            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9253            if (localCpr.hasExternalProcessHandles()) {
9254                if (localCpr.removeExternalProcessHandleLocked(token)) {
9255                    updateOomAdjLocked();
9256                } else {
9257                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9258                            + " with no external reference for token: "
9259                            + token + ".");
9260                }
9261            } else {
9262                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9263                        + " with no external references.");
9264            }
9265        }
9266    }
9267
9268    public final void publishContentProviders(IApplicationThread caller,
9269            List<ContentProviderHolder> providers) {
9270        if (providers == null) {
9271            return;
9272        }
9273
9274        enforceNotIsolatedCaller("publishContentProviders");
9275        synchronized (this) {
9276            final ProcessRecord r = getRecordForAppLocked(caller);
9277            if (DEBUG_MU)
9278                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9279            if (r == null) {
9280                throw new SecurityException(
9281                        "Unable to find app for caller " + caller
9282                      + " (pid=" + Binder.getCallingPid()
9283                      + ") when publishing content providers");
9284            }
9285
9286            final long origId = Binder.clearCallingIdentity();
9287
9288            final int N = providers.size();
9289            for (int i=0; i<N; i++) {
9290                ContentProviderHolder src = providers.get(i);
9291                if (src == null || src.info == null || src.provider == null) {
9292                    continue;
9293                }
9294                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9295                if (DEBUG_MU)
9296                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9297                if (dst != null) {
9298                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9299                    mProviderMap.putProviderByClass(comp, dst);
9300                    String names[] = dst.info.authority.split(";");
9301                    for (int j = 0; j < names.length; j++) {
9302                        mProviderMap.putProviderByName(names[j], dst);
9303                    }
9304
9305                    int NL = mLaunchingProviders.size();
9306                    int j;
9307                    for (j=0; j<NL; j++) {
9308                        if (mLaunchingProviders.get(j) == dst) {
9309                            mLaunchingProviders.remove(j);
9310                            j--;
9311                            NL--;
9312                        }
9313                    }
9314                    synchronized (dst) {
9315                        dst.provider = src.provider;
9316                        dst.proc = r;
9317                        dst.notifyAll();
9318                    }
9319                    updateOomAdjLocked(r);
9320                }
9321            }
9322
9323            Binder.restoreCallingIdentity(origId);
9324        }
9325    }
9326
9327    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9328        ContentProviderConnection conn;
9329        try {
9330            conn = (ContentProviderConnection)connection;
9331        } catch (ClassCastException e) {
9332            String msg ="refContentProvider: " + connection
9333                    + " not a ContentProviderConnection";
9334            Slog.w(TAG, msg);
9335            throw new IllegalArgumentException(msg);
9336        }
9337        if (conn == null) {
9338            throw new NullPointerException("connection is null");
9339        }
9340
9341        synchronized (this) {
9342            if (stable > 0) {
9343                conn.numStableIncs += stable;
9344            }
9345            stable = conn.stableCount + stable;
9346            if (stable < 0) {
9347                throw new IllegalStateException("stableCount < 0: " + stable);
9348            }
9349
9350            if (unstable > 0) {
9351                conn.numUnstableIncs += unstable;
9352            }
9353            unstable = conn.unstableCount + unstable;
9354            if (unstable < 0) {
9355                throw new IllegalStateException("unstableCount < 0: " + unstable);
9356            }
9357
9358            if ((stable+unstable) <= 0) {
9359                throw new IllegalStateException("ref counts can't go to zero here: stable="
9360                        + stable + " unstable=" + unstable);
9361            }
9362            conn.stableCount = stable;
9363            conn.unstableCount = unstable;
9364            return !conn.dead;
9365        }
9366    }
9367
9368    public void unstableProviderDied(IBinder connection) {
9369        ContentProviderConnection conn;
9370        try {
9371            conn = (ContentProviderConnection)connection;
9372        } catch (ClassCastException e) {
9373            String msg ="refContentProvider: " + connection
9374                    + " not a ContentProviderConnection";
9375            Slog.w(TAG, msg);
9376            throw new IllegalArgumentException(msg);
9377        }
9378        if (conn == null) {
9379            throw new NullPointerException("connection is null");
9380        }
9381
9382        // Safely retrieve the content provider associated with the connection.
9383        IContentProvider provider;
9384        synchronized (this) {
9385            provider = conn.provider.provider;
9386        }
9387
9388        if (provider == null) {
9389            // Um, yeah, we're way ahead of you.
9390            return;
9391        }
9392
9393        // Make sure the caller is being honest with us.
9394        if (provider.asBinder().pingBinder()) {
9395            // Er, no, still looks good to us.
9396            synchronized (this) {
9397                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9398                        + " says " + conn + " died, but we don't agree");
9399                return;
9400            }
9401        }
9402
9403        // Well look at that!  It's dead!
9404        synchronized (this) {
9405            if (conn.provider.provider != provider) {
9406                // But something changed...  good enough.
9407                return;
9408            }
9409
9410            ProcessRecord proc = conn.provider.proc;
9411            if (proc == null || proc.thread == null) {
9412                // Seems like the process is already cleaned up.
9413                return;
9414            }
9415
9416            // As far as we're concerned, this is just like receiving a
9417            // death notification...  just a bit prematurely.
9418            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9419                    + ") early provider death");
9420            final long ident = Binder.clearCallingIdentity();
9421            try {
9422                appDiedLocked(proc);
9423            } finally {
9424                Binder.restoreCallingIdentity(ident);
9425            }
9426        }
9427    }
9428
9429    @Override
9430    public void appNotRespondingViaProvider(IBinder connection) {
9431        enforceCallingPermission(
9432                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9433
9434        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9435        if (conn == null) {
9436            Slog.w(TAG, "ContentProviderConnection is null");
9437            return;
9438        }
9439
9440        final ProcessRecord host = conn.provider.proc;
9441        if (host == null) {
9442            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9443            return;
9444        }
9445
9446        final long token = Binder.clearCallingIdentity();
9447        try {
9448            appNotResponding(host, null, null, false, "ContentProvider not responding");
9449        } finally {
9450            Binder.restoreCallingIdentity(token);
9451        }
9452    }
9453
9454    public final void installSystemProviders() {
9455        List<ProviderInfo> providers;
9456        synchronized (this) {
9457            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9458            providers = generateApplicationProvidersLocked(app);
9459            if (providers != null) {
9460                for (int i=providers.size()-1; i>=0; i--) {
9461                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9462                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9463                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9464                                + ": not system .apk");
9465                        providers.remove(i);
9466                    }
9467                }
9468            }
9469        }
9470        if (providers != null) {
9471            mSystemThread.installSystemProviders(providers);
9472        }
9473
9474        mCoreSettingsObserver = new CoreSettingsObserver(this);
9475
9476        //mUsageStatsService.monitorPackages();
9477    }
9478
9479    /**
9480     * Allows apps to retrieve the MIME type of a URI.
9481     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9482     * users, then it does not need permission to access the ContentProvider.
9483     * Either, it needs cross-user uri grants.
9484     *
9485     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9486     *
9487     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9488     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9489     */
9490    public String getProviderMimeType(Uri uri, int userId) {
9491        enforceNotIsolatedCaller("getProviderMimeType");
9492        final String name = uri.getAuthority();
9493        int callingUid = Binder.getCallingUid();
9494        int callingPid = Binder.getCallingPid();
9495        long ident = 0;
9496        boolean clearedIdentity = false;
9497        userId = unsafeConvertIncomingUser(userId);
9498        if (canClearIdentity(callingPid, callingUid, userId)) {
9499            clearedIdentity = true;
9500            ident = Binder.clearCallingIdentity();
9501        }
9502        ContentProviderHolder holder = null;
9503        try {
9504            holder = getContentProviderExternalUnchecked(name, null, userId);
9505            if (holder != null) {
9506                return holder.provider.getType(uri);
9507            }
9508        } catch (RemoteException e) {
9509            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9510            return null;
9511        } finally {
9512            // We need to clear the identity to call removeContentProviderExternalUnchecked
9513            if (!clearedIdentity) {
9514                ident = Binder.clearCallingIdentity();
9515            }
9516            try {
9517                if (holder != null) {
9518                    removeContentProviderExternalUnchecked(name, null, userId);
9519                }
9520            } finally {
9521                Binder.restoreCallingIdentity(ident);
9522            }
9523        }
9524
9525        return null;
9526    }
9527
9528    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9529        if (UserHandle.getUserId(callingUid) == userId) {
9530            return true;
9531        }
9532        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9533                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9534                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9535                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9536                return true;
9537        }
9538        return false;
9539    }
9540
9541    // =========================================================
9542    // GLOBAL MANAGEMENT
9543    // =========================================================
9544
9545    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9546            boolean isolated, int isolatedUid) {
9547        String proc = customProcess != null ? customProcess : info.processName;
9548        BatteryStatsImpl.Uid.Proc ps = null;
9549        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9550        int uid = info.uid;
9551        if (isolated) {
9552            if (isolatedUid == 0) {
9553                int userId = UserHandle.getUserId(uid);
9554                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9555                while (true) {
9556                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9557                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9558                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9559                    }
9560                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9561                    mNextIsolatedProcessUid++;
9562                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9563                        // No process for this uid, use it.
9564                        break;
9565                    }
9566                    stepsLeft--;
9567                    if (stepsLeft <= 0) {
9568                        return null;
9569                    }
9570                }
9571            } else {
9572                // Special case for startIsolatedProcess (internal only), where
9573                // the uid of the isolated process is specified by the caller.
9574                uid = isolatedUid;
9575            }
9576        }
9577        return new ProcessRecord(stats, info, proc, uid);
9578    }
9579
9580    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9581            String abiOverride) {
9582        ProcessRecord app;
9583        if (!isolated) {
9584            app = getProcessRecordLocked(info.processName, info.uid, true);
9585        } else {
9586            app = null;
9587        }
9588
9589        if (app == null) {
9590            app = newProcessRecordLocked(info, null, isolated, 0);
9591            mProcessNames.put(info.processName, app.uid, app);
9592            if (isolated) {
9593                mIsolatedProcesses.put(app.uid, app);
9594            }
9595            updateLruProcessLocked(app, false, null);
9596            updateOomAdjLocked();
9597        }
9598
9599        // This package really, really can not be stopped.
9600        try {
9601            AppGlobals.getPackageManager().setPackageStoppedState(
9602                    info.packageName, false, UserHandle.getUserId(app.uid));
9603        } catch (RemoteException e) {
9604        } catch (IllegalArgumentException e) {
9605            Slog.w(TAG, "Failed trying to unstop package "
9606                    + info.packageName + ": " + e);
9607        }
9608
9609        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9610                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9611            app.persistent = true;
9612            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9613        }
9614        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9615            mPersistentStartingProcesses.add(app);
9616            startProcessLocked(app, "added application", app.processName, abiOverride,
9617                    null /* entryPoint */, null /* entryPointArgs */);
9618        }
9619
9620        return app;
9621    }
9622
9623    public void unhandledBack() {
9624        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9625                "unhandledBack()");
9626
9627        synchronized(this) {
9628            final long origId = Binder.clearCallingIdentity();
9629            try {
9630                getFocusedStack().unhandledBackLocked();
9631            } finally {
9632                Binder.restoreCallingIdentity(origId);
9633            }
9634        }
9635    }
9636
9637    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9638        enforceNotIsolatedCaller("openContentUri");
9639        final int userId = UserHandle.getCallingUserId();
9640        String name = uri.getAuthority();
9641        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9642        ParcelFileDescriptor pfd = null;
9643        if (cph != null) {
9644            // We record the binder invoker's uid in thread-local storage before
9645            // going to the content provider to open the file.  Later, in the code
9646            // that handles all permissions checks, we look for this uid and use
9647            // that rather than the Activity Manager's own uid.  The effect is that
9648            // we do the check against the caller's permissions even though it looks
9649            // to the content provider like the Activity Manager itself is making
9650            // the request.
9651            Binder token = new Binder();
9652            sCallerIdentity.set(new Identity(
9653                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9654            try {
9655                pfd = cph.provider.openFile(null, uri, "r", null, token);
9656            } catch (FileNotFoundException e) {
9657                // do nothing; pfd will be returned null
9658            } finally {
9659                // Ensure that whatever happens, we clean up the identity state
9660                sCallerIdentity.remove();
9661                // Ensure we're done with the provider.
9662                removeContentProviderExternalUnchecked(name, null, userId);
9663            }
9664        } else {
9665            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9666        }
9667        return pfd;
9668    }
9669
9670    // Actually is sleeping or shutting down or whatever else in the future
9671    // is an inactive state.
9672    public boolean isSleepingOrShuttingDown() {
9673        return isSleeping() || mShuttingDown;
9674    }
9675
9676    public boolean isSleeping() {
9677        return mSleeping;
9678    }
9679
9680    void onWakefulnessChanged(int wakefulness) {
9681        synchronized(this) {
9682            mWakefulness = wakefulness;
9683            updateSleepIfNeededLocked();
9684        }
9685    }
9686
9687    void finishRunningVoiceLocked() {
9688        if (mRunningVoice) {
9689            mRunningVoice = false;
9690            updateSleepIfNeededLocked();
9691        }
9692    }
9693
9694    void updateSleepIfNeededLocked() {
9695        if (mSleeping && !shouldSleepLocked()) {
9696            mSleeping = false;
9697            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9698        } else if (!mSleeping && shouldSleepLocked()) {
9699            mSleeping = true;
9700            mStackSupervisor.goingToSleepLocked();
9701
9702            // Initialize the wake times of all processes.
9703            checkExcessivePowerUsageLocked(false);
9704            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9705            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9706            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9707        }
9708    }
9709
9710    private boolean shouldSleepLocked() {
9711        // Resume applications while running a voice interactor.
9712        if (mRunningVoice) {
9713            return false;
9714        }
9715
9716        switch (mWakefulness) {
9717            case PowerManagerInternal.WAKEFULNESS_AWAKE:
9718            case PowerManagerInternal.WAKEFULNESS_DREAMING:
9719                // If we're interactive but applications are already paused then defer
9720                // resuming them until the lock screen is hidden.
9721                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
9722            case PowerManagerInternal.WAKEFULNESS_DOZING:
9723                // If we're dozing then pause applications whenever the lock screen is shown.
9724                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
9725            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
9726            default:
9727                // If we're asleep then pause applications unconditionally.
9728                return true;
9729        }
9730    }
9731
9732    /** Pokes the task persister. */
9733    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9734        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9735            // Never persist the home stack.
9736            return;
9737        }
9738        mTaskPersister.wakeup(task, flush);
9739    }
9740
9741    /** Notifies all listeners when the task stack has changed. */
9742    void notifyTaskStackChangedLocked() {
9743        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
9744        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
9745        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
9746    }
9747
9748    @Override
9749    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
9750        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
9751    }
9752
9753    @Override
9754    public boolean shutdown(int timeout) {
9755        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9756                != PackageManager.PERMISSION_GRANTED) {
9757            throw new SecurityException("Requires permission "
9758                    + android.Manifest.permission.SHUTDOWN);
9759        }
9760
9761        boolean timedout = false;
9762
9763        synchronized(this) {
9764            mShuttingDown = true;
9765            updateEventDispatchingLocked();
9766            timedout = mStackSupervisor.shutdownLocked(timeout);
9767        }
9768
9769        mAppOpsService.shutdown();
9770        if (mUsageStatsService != null) {
9771            mUsageStatsService.prepareShutdown();
9772        }
9773        mBatteryStatsService.shutdown();
9774        synchronized (this) {
9775            mProcessStats.shutdownLocked();
9776            notifyTaskPersisterLocked(null, true);
9777        }
9778
9779        return timedout;
9780    }
9781
9782    public final void activitySlept(IBinder token) {
9783        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
9784
9785        final long origId = Binder.clearCallingIdentity();
9786
9787        synchronized (this) {
9788            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9789            if (r != null) {
9790                mStackSupervisor.activitySleptLocked(r);
9791            }
9792        }
9793
9794        Binder.restoreCallingIdentity(origId);
9795    }
9796
9797    private String lockScreenShownToString() {
9798        switch (mLockScreenShown) {
9799            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
9800            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
9801            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
9802            default: return "Unknown=" + mLockScreenShown;
9803        }
9804    }
9805
9806    void logLockScreen(String msg) {
9807        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
9808                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
9809                + PowerManagerInternal.wakefulnessToString(mWakefulness)
9810                + " mSleeping=" + mSleeping);
9811    }
9812
9813    void startRunningVoiceLocked() {
9814        if (!mRunningVoice) {
9815            mRunningVoice = true;
9816            updateSleepIfNeededLocked();
9817        }
9818    }
9819
9820    private void updateEventDispatchingLocked() {
9821        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
9822    }
9823
9824    public void setLockScreenShown(boolean shown) {
9825        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9826                != PackageManager.PERMISSION_GRANTED) {
9827            throw new SecurityException("Requires permission "
9828                    + android.Manifest.permission.DEVICE_POWER);
9829        }
9830
9831        synchronized(this) {
9832            long ident = Binder.clearCallingIdentity();
9833            try {
9834                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9835                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
9836                updateSleepIfNeededLocked();
9837            } finally {
9838                Binder.restoreCallingIdentity(ident);
9839            }
9840        }
9841    }
9842
9843    @Override
9844    public void stopAppSwitches() {
9845        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9846                != PackageManager.PERMISSION_GRANTED) {
9847            throw new SecurityException("Requires permission "
9848                    + android.Manifest.permission.STOP_APP_SWITCHES);
9849        }
9850
9851        synchronized(this) {
9852            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9853                    + APP_SWITCH_DELAY_TIME;
9854            mDidAppSwitch = false;
9855            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9856            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9857            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9858        }
9859    }
9860
9861    public void resumeAppSwitches() {
9862        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9863                != PackageManager.PERMISSION_GRANTED) {
9864            throw new SecurityException("Requires permission "
9865                    + android.Manifest.permission.STOP_APP_SWITCHES);
9866        }
9867
9868        synchronized(this) {
9869            // Note that we don't execute any pending app switches... we will
9870            // let those wait until either the timeout, or the next start
9871            // activity request.
9872            mAppSwitchesAllowedTime = 0;
9873        }
9874    }
9875
9876    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
9877            int callingPid, int callingUid, String name) {
9878        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9879            return true;
9880        }
9881
9882        int perm = checkComponentPermission(
9883                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
9884                sourceUid, -1, true);
9885        if (perm == PackageManager.PERMISSION_GRANTED) {
9886            return true;
9887        }
9888
9889        // If the actual IPC caller is different from the logical source, then
9890        // also see if they are allowed to control app switches.
9891        if (callingUid != -1 && callingUid != sourceUid) {
9892            perm = checkComponentPermission(
9893                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9894                    callingUid, -1, true);
9895            if (perm == PackageManager.PERMISSION_GRANTED) {
9896                return true;
9897            }
9898        }
9899
9900        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
9901        return false;
9902    }
9903
9904    public void setDebugApp(String packageName, boolean waitForDebugger,
9905            boolean persistent) {
9906        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9907                "setDebugApp()");
9908
9909        long ident = Binder.clearCallingIdentity();
9910        try {
9911            // Note that this is not really thread safe if there are multiple
9912            // callers into it at the same time, but that's not a situation we
9913            // care about.
9914            if (persistent) {
9915                final ContentResolver resolver = mContext.getContentResolver();
9916                Settings.Global.putString(
9917                    resolver, Settings.Global.DEBUG_APP,
9918                    packageName);
9919                Settings.Global.putInt(
9920                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9921                    waitForDebugger ? 1 : 0);
9922            }
9923
9924            synchronized (this) {
9925                if (!persistent) {
9926                    mOrigDebugApp = mDebugApp;
9927                    mOrigWaitForDebugger = mWaitForDebugger;
9928                }
9929                mDebugApp = packageName;
9930                mWaitForDebugger = waitForDebugger;
9931                mDebugTransient = !persistent;
9932                if (packageName != null) {
9933                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9934                            false, UserHandle.USER_ALL, "set debug app");
9935                }
9936            }
9937        } finally {
9938            Binder.restoreCallingIdentity(ident);
9939        }
9940    }
9941
9942    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9943        synchronized (this) {
9944            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9945            if (!isDebuggable) {
9946                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9947                    throw new SecurityException("Process not debuggable: " + app.packageName);
9948                }
9949            }
9950
9951            mOpenGlTraceApp = processName;
9952        }
9953    }
9954
9955    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
9956        synchronized (this) {
9957            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9958            if (!isDebuggable) {
9959                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9960                    throw new SecurityException("Process not debuggable: " + app.packageName);
9961                }
9962            }
9963            mProfileApp = processName;
9964            mProfileFile = profilerInfo.profileFile;
9965            if (mProfileFd != null) {
9966                try {
9967                    mProfileFd.close();
9968                } catch (IOException e) {
9969                }
9970                mProfileFd = null;
9971            }
9972            mProfileFd = profilerInfo.profileFd;
9973            mSamplingInterval = profilerInfo.samplingInterval;
9974            mAutoStopProfiler = profilerInfo.autoStopProfiler;
9975            mProfileType = 0;
9976        }
9977    }
9978
9979    @Override
9980    public void setAlwaysFinish(boolean enabled) {
9981        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9982                "setAlwaysFinish()");
9983
9984        Settings.Global.putInt(
9985                mContext.getContentResolver(),
9986                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9987
9988        synchronized (this) {
9989            mAlwaysFinishActivities = enabled;
9990        }
9991    }
9992
9993    @Override
9994    public void setActivityController(IActivityController controller) {
9995        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9996                "setActivityController()");
9997        synchronized (this) {
9998            mController = controller;
9999            Watchdog.getInstance().setActivityController(controller);
10000        }
10001    }
10002
10003    @Override
10004    public void setUserIsMonkey(boolean userIsMonkey) {
10005        synchronized (this) {
10006            synchronized (mPidsSelfLocked) {
10007                final int callingPid = Binder.getCallingPid();
10008                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10009                if (precessRecord == null) {
10010                    throw new SecurityException("Unknown process: " + callingPid);
10011                }
10012                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10013                    throw new SecurityException("Only an instrumentation process "
10014                            + "with a UiAutomation can call setUserIsMonkey");
10015                }
10016            }
10017            mUserIsMonkey = userIsMonkey;
10018        }
10019    }
10020
10021    @Override
10022    public boolean isUserAMonkey() {
10023        synchronized (this) {
10024            // If there is a controller also implies the user is a monkey.
10025            return (mUserIsMonkey || mController != null);
10026        }
10027    }
10028
10029    public void requestBugReport() {
10030        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10031        SystemProperties.set("ctl.start", "bugreport");
10032    }
10033
10034    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10035        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10036    }
10037
10038    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10039        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10040            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10041        }
10042        return KEY_DISPATCHING_TIMEOUT;
10043    }
10044
10045    @Override
10046    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10047        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10048                != PackageManager.PERMISSION_GRANTED) {
10049            throw new SecurityException("Requires permission "
10050                    + android.Manifest.permission.FILTER_EVENTS);
10051        }
10052        ProcessRecord proc;
10053        long timeout;
10054        synchronized (this) {
10055            synchronized (mPidsSelfLocked) {
10056                proc = mPidsSelfLocked.get(pid);
10057            }
10058            timeout = getInputDispatchingTimeoutLocked(proc);
10059        }
10060
10061        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10062            return -1;
10063        }
10064
10065        return timeout;
10066    }
10067
10068    /**
10069     * Handle input dispatching timeouts.
10070     * Returns whether input dispatching should be aborted or not.
10071     */
10072    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10073            final ActivityRecord activity, final ActivityRecord parent,
10074            final boolean aboveSystem, String reason) {
10075        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10076                != PackageManager.PERMISSION_GRANTED) {
10077            throw new SecurityException("Requires permission "
10078                    + android.Manifest.permission.FILTER_EVENTS);
10079        }
10080
10081        final String annotation;
10082        if (reason == null) {
10083            annotation = "Input dispatching timed out";
10084        } else {
10085            annotation = "Input dispatching timed out (" + reason + ")";
10086        }
10087
10088        if (proc != null) {
10089            synchronized (this) {
10090                if (proc.debugging) {
10091                    return false;
10092                }
10093
10094                if (mDidDexOpt) {
10095                    // Give more time since we were dexopting.
10096                    mDidDexOpt = false;
10097                    return false;
10098                }
10099
10100                if (proc.instrumentationClass != null) {
10101                    Bundle info = new Bundle();
10102                    info.putString("shortMsg", "keyDispatchingTimedOut");
10103                    info.putString("longMsg", annotation);
10104                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10105                    return true;
10106                }
10107            }
10108            mHandler.post(new Runnable() {
10109                @Override
10110                public void run() {
10111                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10112                }
10113            });
10114        }
10115
10116        return true;
10117    }
10118
10119    @Override
10120    public Bundle getAssistContextExtras(int requestType) {
10121        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10122                UserHandle.getCallingUserId());
10123        if (pae == null) {
10124            return null;
10125        }
10126        synchronized (pae) {
10127            while (!pae.haveResult) {
10128                try {
10129                    pae.wait();
10130                } catch (InterruptedException e) {
10131                }
10132            }
10133        }
10134        synchronized (this) {
10135            buildAssistBundleLocked(pae, pae.result);
10136            mPendingAssistExtras.remove(pae);
10137            mHandler.removeCallbacks(pae);
10138        }
10139        return pae.extras;
10140    }
10141
10142    @Override
10143    public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
10144        enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId());
10145    }
10146
10147    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10148            IResultReceiver receiver, int userHandle) {
10149        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10150                "enqueueAssistContext()");
10151        synchronized (this) {
10152            ActivityRecord activity = getFocusedStack().topActivity();
10153            if (activity == null) {
10154                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10155                return null;
10156            }
10157            if (activity.app == null || activity.app.thread == null) {
10158                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10159                return null;
10160            }
10161            if (activity.app.pid == Binder.getCallingPid()) {
10162                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10163                return null;
10164            }
10165            PendingAssistExtras pae;
10166            Bundle extras = new Bundle();
10167            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10168            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10169            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10170            try {
10171                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10172                        requestType);
10173                mPendingAssistExtras.add(pae);
10174                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10175            } catch (RemoteException e) {
10176                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10177                return null;
10178            }
10179            return pae;
10180        }
10181    }
10182
10183    void pendingAssistExtrasTimedOutLocked(PendingAssistExtras pae) {
10184        mPendingAssistExtras.remove(pae);
10185        if (pae.receiver != null) {
10186            // Caller wants result sent back to them.
10187            try {
10188                pae.receiver.send(0, null);
10189            } catch (RemoteException e) {
10190            }
10191        }
10192    }
10193
10194    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10195        if (result != null) {
10196            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10197        }
10198        if (pae.hint != null) {
10199            pae.extras.putBoolean(pae.hint, true);
10200        }
10201    }
10202
10203    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10204        PendingAssistExtras pae = (PendingAssistExtras)token;
10205        synchronized (pae) {
10206            pae.result = extras;
10207            pae.haveResult = true;
10208            pae.notifyAll();
10209            if (pae.intent == null && pae.receiver == null) {
10210                // Caller is just waiting for the result.
10211                return;
10212            }
10213        }
10214
10215        // We are now ready to launch the assist activity.
10216        synchronized (this) {
10217            buildAssistBundleLocked(pae, extras);
10218            boolean exists = mPendingAssistExtras.remove(pae);
10219            mHandler.removeCallbacks(pae);
10220            if (!exists) {
10221                // Timed out.
10222                return;
10223            }
10224            if (pae.receiver != null) {
10225                // Caller wants result sent back to them.
10226                try {
10227                    pae.receiver.send(0, pae.extras);
10228                } catch (RemoteException e) {
10229                }
10230                return;
10231            }
10232        }
10233        pae.intent.replaceExtras(pae.extras);
10234        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10235                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10236                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10237        closeSystemDialogs("assist");
10238        try {
10239            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10240        } catch (ActivityNotFoundException e) {
10241            Slog.w(TAG, "No activity to handle assist action.", e);
10242        }
10243    }
10244
10245    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10246        return enqueueAssistContext(requestType, intent, hint, null, userHandle) != null;
10247    }
10248
10249    public void registerProcessObserver(IProcessObserver observer) {
10250        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10251                "registerProcessObserver()");
10252        synchronized (this) {
10253            mProcessObservers.register(observer);
10254        }
10255    }
10256
10257    @Override
10258    public void unregisterProcessObserver(IProcessObserver observer) {
10259        synchronized (this) {
10260            mProcessObservers.unregister(observer);
10261        }
10262    }
10263
10264    @Override
10265    public boolean convertFromTranslucent(IBinder token) {
10266        final long origId = Binder.clearCallingIdentity();
10267        try {
10268            synchronized (this) {
10269                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10270                if (r == null) {
10271                    return false;
10272                }
10273                final boolean translucentChanged = r.changeWindowTranslucency(true);
10274                if (translucentChanged) {
10275                    r.task.stack.releaseBackgroundResources(r);
10276                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10277                }
10278                mWindowManager.setAppFullscreen(token, true);
10279                return translucentChanged;
10280            }
10281        } finally {
10282            Binder.restoreCallingIdentity(origId);
10283        }
10284    }
10285
10286    @Override
10287    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10288        final long origId = Binder.clearCallingIdentity();
10289        try {
10290            synchronized (this) {
10291                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10292                if (r == null) {
10293                    return false;
10294                }
10295                int index = r.task.mActivities.lastIndexOf(r);
10296                if (index > 0) {
10297                    ActivityRecord under = r.task.mActivities.get(index - 1);
10298                    under.returningOptions = options;
10299                }
10300                final boolean translucentChanged = r.changeWindowTranslucency(false);
10301                if (translucentChanged) {
10302                    r.task.stack.convertActivityToTranslucent(r);
10303                }
10304                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10305                mWindowManager.setAppFullscreen(token, false);
10306                return translucentChanged;
10307            }
10308        } finally {
10309            Binder.restoreCallingIdentity(origId);
10310        }
10311    }
10312
10313    @Override
10314    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10315        final long origId = Binder.clearCallingIdentity();
10316        try {
10317            synchronized (this) {
10318                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10319                if (r != null) {
10320                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10321                }
10322            }
10323            return false;
10324        } finally {
10325            Binder.restoreCallingIdentity(origId);
10326        }
10327    }
10328
10329    @Override
10330    public boolean isBackgroundVisibleBehind(IBinder token) {
10331        final long origId = Binder.clearCallingIdentity();
10332        try {
10333            synchronized (this) {
10334                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10335                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10336                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10337                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10338                return visible;
10339            }
10340        } finally {
10341            Binder.restoreCallingIdentity(origId);
10342        }
10343    }
10344
10345    @Override
10346    public ActivityOptions getActivityOptions(IBinder token) {
10347        final long origId = Binder.clearCallingIdentity();
10348        try {
10349            synchronized (this) {
10350                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10351                if (r != null) {
10352                    final ActivityOptions activityOptions = r.pendingOptions;
10353                    r.pendingOptions = null;
10354                    return activityOptions;
10355                }
10356                return null;
10357            }
10358        } finally {
10359            Binder.restoreCallingIdentity(origId);
10360        }
10361    }
10362
10363    @Override
10364    public void setImmersive(IBinder token, boolean immersive) {
10365        synchronized(this) {
10366            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10367            if (r == null) {
10368                throw new IllegalArgumentException();
10369            }
10370            r.immersive = immersive;
10371
10372            // update associated state if we're frontmost
10373            if (r == mFocusedActivity) {
10374                if (DEBUG_IMMERSIVE) {
10375                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10376                }
10377                applyUpdateLockStateLocked(r);
10378            }
10379        }
10380    }
10381
10382    @Override
10383    public boolean isImmersive(IBinder token) {
10384        synchronized (this) {
10385            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10386            if (r == null) {
10387                throw new IllegalArgumentException();
10388            }
10389            return r.immersive;
10390        }
10391    }
10392
10393    public boolean isTopActivityImmersive() {
10394        enforceNotIsolatedCaller("startActivity");
10395        synchronized (this) {
10396            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10397            return (r != null) ? r.immersive : false;
10398        }
10399    }
10400
10401    @Override
10402    public boolean isTopOfTask(IBinder token) {
10403        synchronized (this) {
10404            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10405            if (r == null) {
10406                throw new IllegalArgumentException();
10407            }
10408            return r.task.getTopActivity() == r;
10409        }
10410    }
10411
10412    public final void enterSafeMode() {
10413        synchronized(this) {
10414            // It only makes sense to do this before the system is ready
10415            // and started launching other packages.
10416            if (!mSystemReady) {
10417                try {
10418                    AppGlobals.getPackageManager().enterSafeMode();
10419                } catch (RemoteException e) {
10420                }
10421            }
10422
10423            mSafeMode = true;
10424        }
10425    }
10426
10427    public final void showSafeModeOverlay() {
10428        View v = LayoutInflater.from(mContext).inflate(
10429                com.android.internal.R.layout.safe_mode, null);
10430        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10431        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10432        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10433        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10434        lp.gravity = Gravity.BOTTOM | Gravity.START;
10435        lp.format = v.getBackground().getOpacity();
10436        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10437                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10438        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10439        ((WindowManager)mContext.getSystemService(
10440                Context.WINDOW_SERVICE)).addView(v, lp);
10441    }
10442
10443    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10444        if (!(sender instanceof PendingIntentRecord)) {
10445            return;
10446        }
10447        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10448        synchronized (stats) {
10449            if (mBatteryStatsService.isOnBattery()) {
10450                mBatteryStatsService.enforceCallingPermission();
10451                PendingIntentRecord rec = (PendingIntentRecord)sender;
10452                int MY_UID = Binder.getCallingUid();
10453                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10454                BatteryStatsImpl.Uid.Pkg pkg =
10455                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10456                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10457                pkg.incWakeupsLocked();
10458            }
10459        }
10460    }
10461
10462    public boolean killPids(int[] pids, String pReason, boolean secure) {
10463        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10464            throw new SecurityException("killPids only available to the system");
10465        }
10466        String reason = (pReason == null) ? "Unknown" : pReason;
10467        // XXX Note: don't acquire main activity lock here, because the window
10468        // manager calls in with its locks held.
10469
10470        boolean killed = false;
10471        synchronized (mPidsSelfLocked) {
10472            int[] types = new int[pids.length];
10473            int worstType = 0;
10474            for (int i=0; i<pids.length; i++) {
10475                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10476                if (proc != null) {
10477                    int type = proc.setAdj;
10478                    types[i] = type;
10479                    if (type > worstType) {
10480                        worstType = type;
10481                    }
10482                }
10483            }
10484
10485            // If the worst oom_adj is somewhere in the cached proc LRU range,
10486            // then constrain it so we will kill all cached procs.
10487            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10488                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10489                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10490            }
10491
10492            // If this is not a secure call, don't let it kill processes that
10493            // are important.
10494            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10495                worstType = ProcessList.SERVICE_ADJ;
10496            }
10497
10498            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10499            for (int i=0; i<pids.length; i++) {
10500                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10501                if (proc == null) {
10502                    continue;
10503                }
10504                int adj = proc.setAdj;
10505                if (adj >= worstType && !proc.killedByAm) {
10506                    proc.kill(reason, true);
10507                    killed = true;
10508                }
10509            }
10510        }
10511        return killed;
10512    }
10513
10514    @Override
10515    public void killUid(int uid, String reason) {
10516        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10517            throw new SecurityException("killUid only available to the system");
10518        }
10519        synchronized (this) {
10520            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10521                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10522                    reason != null ? reason : "kill uid");
10523        }
10524    }
10525
10526    @Override
10527    public boolean killProcessesBelowForeground(String reason) {
10528        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10529            throw new SecurityException("killProcessesBelowForeground() only available to system");
10530        }
10531
10532        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10533    }
10534
10535    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10536        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10537            throw new SecurityException("killProcessesBelowAdj() only available to system");
10538        }
10539
10540        boolean killed = false;
10541        synchronized (mPidsSelfLocked) {
10542            final int size = mPidsSelfLocked.size();
10543            for (int i = 0; i < size; i++) {
10544                final int pid = mPidsSelfLocked.keyAt(i);
10545                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10546                if (proc == null) continue;
10547
10548                final int adj = proc.setAdj;
10549                if (adj > belowAdj && !proc.killedByAm) {
10550                    proc.kill(reason, true);
10551                    killed = true;
10552                }
10553            }
10554        }
10555        return killed;
10556    }
10557
10558    @Override
10559    public void hang(final IBinder who, boolean allowRestart) {
10560        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10561                != PackageManager.PERMISSION_GRANTED) {
10562            throw new SecurityException("Requires permission "
10563                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10564        }
10565
10566        final IBinder.DeathRecipient death = new DeathRecipient() {
10567            @Override
10568            public void binderDied() {
10569                synchronized (this) {
10570                    notifyAll();
10571                }
10572            }
10573        };
10574
10575        try {
10576            who.linkToDeath(death, 0);
10577        } catch (RemoteException e) {
10578            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10579            return;
10580        }
10581
10582        synchronized (this) {
10583            Watchdog.getInstance().setAllowRestart(allowRestart);
10584            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10585            synchronized (death) {
10586                while (who.isBinderAlive()) {
10587                    try {
10588                        death.wait();
10589                    } catch (InterruptedException e) {
10590                    }
10591                }
10592            }
10593            Watchdog.getInstance().setAllowRestart(true);
10594        }
10595    }
10596
10597    @Override
10598    public void restart() {
10599        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10600                != PackageManager.PERMISSION_GRANTED) {
10601            throw new SecurityException("Requires permission "
10602                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10603        }
10604
10605        Log.i(TAG, "Sending shutdown broadcast...");
10606
10607        BroadcastReceiver br = new BroadcastReceiver() {
10608            @Override public void onReceive(Context context, Intent intent) {
10609                // Now the broadcast is done, finish up the low-level shutdown.
10610                Log.i(TAG, "Shutting down activity manager...");
10611                shutdown(10000);
10612                Log.i(TAG, "Shutdown complete, restarting!");
10613                Process.killProcess(Process.myPid());
10614                System.exit(10);
10615            }
10616        };
10617
10618        // First send the high-level shut down broadcast.
10619        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10620        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10621        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10622        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10623        mContext.sendOrderedBroadcastAsUser(intent,
10624                UserHandle.ALL, null, br, mHandler, 0, null, null);
10625        */
10626        br.onReceive(mContext, intent);
10627    }
10628
10629    private long getLowRamTimeSinceIdle(long now) {
10630        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10631    }
10632
10633    @Override
10634    public void performIdleMaintenance() {
10635        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10636                != PackageManager.PERMISSION_GRANTED) {
10637            throw new SecurityException("Requires permission "
10638                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10639        }
10640
10641        synchronized (this) {
10642            final long now = SystemClock.uptimeMillis();
10643            final long timeSinceLastIdle = now - mLastIdleTime;
10644            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10645            mLastIdleTime = now;
10646            mLowRamTimeSinceLastIdle = 0;
10647            if (mLowRamStartTime != 0) {
10648                mLowRamStartTime = now;
10649            }
10650
10651            StringBuilder sb = new StringBuilder(128);
10652            sb.append("Idle maintenance over ");
10653            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10654            sb.append(" low RAM for ");
10655            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10656            Slog.i(TAG, sb.toString());
10657
10658            // If at least 1/3 of our time since the last idle period has been spent
10659            // with RAM low, then we want to kill processes.
10660            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10661
10662            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10663                ProcessRecord proc = mLruProcesses.get(i);
10664                if (proc.notCachedSinceIdle) {
10665                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10666                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10667                        if (doKilling && proc.initialIdlePss != 0
10668                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10669                            sb = new StringBuilder(128);
10670                            sb.append("Kill");
10671                            sb.append(proc.processName);
10672                            sb.append(" in idle maint: pss=");
10673                            sb.append(proc.lastPss);
10674                            sb.append(", initialPss=");
10675                            sb.append(proc.initialIdlePss);
10676                            sb.append(", period=");
10677                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10678                            sb.append(", lowRamPeriod=");
10679                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10680                            Slog.wtfQuiet(TAG, sb.toString());
10681                            proc.kill("idle maint (pss " + proc.lastPss
10682                                    + " from " + proc.initialIdlePss + ")", true);
10683                        }
10684                    }
10685                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10686                    proc.notCachedSinceIdle = true;
10687                    proc.initialIdlePss = 0;
10688                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10689                            mTestPssMode, isSleeping(), now);
10690                }
10691            }
10692
10693            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10694            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10695        }
10696    }
10697
10698    private void retrieveSettings() {
10699        final ContentResolver resolver = mContext.getContentResolver();
10700        String debugApp = Settings.Global.getString(
10701            resolver, Settings.Global.DEBUG_APP);
10702        boolean waitForDebugger = Settings.Global.getInt(
10703            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10704        boolean alwaysFinishActivities = Settings.Global.getInt(
10705            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10706        boolean forceRtl = Settings.Global.getInt(
10707                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10708        // Transfer any global setting for forcing RTL layout, into a System Property
10709        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10710
10711        Configuration configuration = new Configuration();
10712        Settings.System.getConfiguration(resolver, configuration);
10713        if (forceRtl) {
10714            // This will take care of setting the correct layout direction flags
10715            configuration.setLayoutDirection(configuration.locale);
10716        }
10717
10718        synchronized (this) {
10719            mDebugApp = mOrigDebugApp = debugApp;
10720            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10721            mAlwaysFinishActivities = alwaysFinishActivities;
10722            // This happens before any activities are started, so we can
10723            // change mConfiguration in-place.
10724            updateConfigurationLocked(configuration, null, false, true);
10725            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10726        }
10727    }
10728
10729    /** Loads resources after the current configuration has been set. */
10730    private void loadResourcesOnSystemReady() {
10731        final Resources res = mContext.getResources();
10732        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10733        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10734        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10735    }
10736
10737    public boolean testIsSystemReady() {
10738        // no need to synchronize(this) just to read & return the value
10739        return mSystemReady;
10740    }
10741
10742    private static File getCalledPreBootReceiversFile() {
10743        File dataDir = Environment.getDataDirectory();
10744        File systemDir = new File(dataDir, "system");
10745        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10746        return fname;
10747    }
10748
10749    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10750        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10751        File file = getCalledPreBootReceiversFile();
10752        FileInputStream fis = null;
10753        try {
10754            fis = new FileInputStream(file);
10755            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10756            int fvers = dis.readInt();
10757            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10758                String vers = dis.readUTF();
10759                String codename = dis.readUTF();
10760                String build = dis.readUTF();
10761                if (android.os.Build.VERSION.RELEASE.equals(vers)
10762                        && android.os.Build.VERSION.CODENAME.equals(codename)
10763                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10764                    int num = dis.readInt();
10765                    while (num > 0) {
10766                        num--;
10767                        String pkg = dis.readUTF();
10768                        String cls = dis.readUTF();
10769                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10770                    }
10771                }
10772            }
10773        } catch (FileNotFoundException e) {
10774        } catch (IOException e) {
10775            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10776        } finally {
10777            if (fis != null) {
10778                try {
10779                    fis.close();
10780                } catch (IOException e) {
10781                }
10782            }
10783        }
10784        return lastDoneReceivers;
10785    }
10786
10787    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10788        File file = getCalledPreBootReceiversFile();
10789        FileOutputStream fos = null;
10790        DataOutputStream dos = null;
10791        try {
10792            fos = new FileOutputStream(file);
10793            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10794            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10795            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10796            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10797            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10798            dos.writeInt(list.size());
10799            for (int i=0; i<list.size(); i++) {
10800                dos.writeUTF(list.get(i).getPackageName());
10801                dos.writeUTF(list.get(i).getClassName());
10802            }
10803        } catch (IOException e) {
10804            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10805            file.delete();
10806        } finally {
10807            FileUtils.sync(fos);
10808            if (dos != null) {
10809                try {
10810                    dos.close();
10811                } catch (IOException e) {
10812                    // TODO Auto-generated catch block
10813                    e.printStackTrace();
10814                }
10815            }
10816        }
10817    }
10818
10819    final class PreBootContinuation extends IIntentReceiver.Stub {
10820        final Intent intent;
10821        final Runnable onFinishCallback;
10822        final ArrayList<ComponentName> doneReceivers;
10823        final List<ResolveInfo> ris;
10824        final int[] users;
10825        int lastRi = -1;
10826        int curRi = 0;
10827        int curUser = 0;
10828
10829        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
10830                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
10831            intent = _intent;
10832            onFinishCallback = _onFinishCallback;
10833            doneReceivers = _doneReceivers;
10834            ris = _ris;
10835            users = _users;
10836        }
10837
10838        void go() {
10839            if (lastRi != curRi) {
10840                ActivityInfo ai = ris.get(curRi).activityInfo;
10841                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10842                intent.setComponent(comp);
10843                doneReceivers.add(comp);
10844                lastRi = curRi;
10845                CharSequence label = ai.loadLabel(mContext.getPackageManager());
10846                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
10847            }
10848            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
10849                    + " for user " + users[curUser]);
10850            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
10851            broadcastIntentLocked(null, null, intent, null, this,
10852                    0, null, null, null, AppOpsManager.OP_NONE,
10853                    true, false, MY_PID, Process.SYSTEM_UID,
10854                    users[curUser]);
10855        }
10856
10857        public void performReceive(Intent intent, int resultCode,
10858                String data, Bundle extras, boolean ordered,
10859                boolean sticky, int sendingUser) {
10860            curUser++;
10861            if (curUser >= users.length) {
10862                curUser = 0;
10863                curRi++;
10864                if (curRi >= ris.size()) {
10865                    // All done sending broadcasts!
10866                    if (onFinishCallback != null) {
10867                        // The raw IIntentReceiver interface is called
10868                        // with the AM lock held, so redispatch to
10869                        // execute our code without the lock.
10870                        mHandler.post(onFinishCallback);
10871                    }
10872                    return;
10873                }
10874            }
10875            go();
10876        }
10877    }
10878
10879    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10880            ArrayList<ComponentName> doneReceivers, int userId) {
10881        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10882        List<ResolveInfo> ris = null;
10883        try {
10884            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10885                    intent, null, 0, userId);
10886        } catch (RemoteException e) {
10887        }
10888        if (ris == null) {
10889            return false;
10890        }
10891        for (int i=ris.size()-1; i>=0; i--) {
10892            if ((ris.get(i).activityInfo.applicationInfo.flags
10893                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
10894                ris.remove(i);
10895            }
10896        }
10897        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10898
10899        // For User 0, load the version number. When delivering to a new user, deliver
10900        // to all receivers.
10901        if (userId == UserHandle.USER_OWNER) {
10902            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10903            for (int i=0; i<ris.size(); i++) {
10904                ActivityInfo ai = ris.get(i).activityInfo;
10905                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10906                if (false && lastDoneReceivers.contains(comp)) {
10907                    // We already did the pre boot receiver for this app with the current
10908                    // platform version, so don't do it again...
10909                    ris.remove(i);
10910                    i--;
10911                    // ...however, do keep it as one that has been done, so we don't
10912                    // forget about it when rewriting the file of last done receivers.
10913                    doneReceivers.add(comp);
10914                }
10915            }
10916        }
10917
10918        if (ris.size() <= 0) {
10919            return false;
10920        }
10921
10922        // If primary user, send broadcast to all available users, else just to userId
10923        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10924                : new int[] { userId };
10925        if (users.length <= 0) {
10926            return false;
10927        }
10928
10929        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
10930                ris, users);
10931        cont.go();
10932        return true;
10933    }
10934
10935    public void systemReady(final Runnable goingCallback) {
10936        synchronized(this) {
10937            if (mSystemReady) {
10938                // If we're done calling all the receivers, run the next "boot phase" passed in
10939                // by the SystemServer
10940                if (goingCallback != null) {
10941                    goingCallback.run();
10942                }
10943                return;
10944            }
10945
10946            // Make sure we have the current profile info, since it is needed for
10947            // security checks.
10948            updateCurrentProfileIdsLocked();
10949
10950            mRecentTasks.clear();
10951            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
10952            mTaskPersister.restoreTasksFromOtherDeviceLocked();
10953            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
10954            mTaskPersister.startPersisting();
10955
10956            // Check to see if there are any update receivers to run.
10957            if (!mDidUpdate) {
10958                if (mWaitingUpdate) {
10959                    return;
10960                }
10961                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10962                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10963                    public void run() {
10964                        synchronized (ActivityManagerService.this) {
10965                            mDidUpdate = true;
10966                        }
10967                        showBootMessage(mContext.getText(
10968                                R.string.android_upgrading_complete),
10969                                false);
10970                        writeLastDonePreBootReceivers(doneReceivers);
10971                        systemReady(goingCallback);
10972                    }
10973                }, doneReceivers, UserHandle.USER_OWNER);
10974
10975                if (mWaitingUpdate) {
10976                    return;
10977                }
10978                mDidUpdate = true;
10979            }
10980
10981            mAppOpsService.systemReady();
10982            mSystemReady = true;
10983        }
10984
10985        ArrayList<ProcessRecord> procsToKill = null;
10986        synchronized(mPidsSelfLocked) {
10987            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10988                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10989                if (!isAllowedWhileBooting(proc.info)){
10990                    if (procsToKill == null) {
10991                        procsToKill = new ArrayList<ProcessRecord>();
10992                    }
10993                    procsToKill.add(proc);
10994                }
10995            }
10996        }
10997
10998        synchronized(this) {
10999            if (procsToKill != null) {
11000                for (int i=procsToKill.size()-1; i>=0; i--) {
11001                    ProcessRecord proc = procsToKill.get(i);
11002                    Slog.i(TAG, "Removing system update proc: " + proc);
11003                    removeProcessLocked(proc, true, false, "system update done");
11004                }
11005            }
11006
11007            // Now that we have cleaned up any update processes, we
11008            // are ready to start launching real processes and know that
11009            // we won't trample on them any more.
11010            mProcessesReady = true;
11011        }
11012
11013        Slog.i(TAG, "System now ready");
11014        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11015            SystemClock.uptimeMillis());
11016
11017        synchronized(this) {
11018            // Make sure we have no pre-ready processes sitting around.
11019
11020            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11021                ResolveInfo ri = mContext.getPackageManager()
11022                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11023                                STOCK_PM_FLAGS);
11024                CharSequence errorMsg = null;
11025                if (ri != null) {
11026                    ActivityInfo ai = ri.activityInfo;
11027                    ApplicationInfo app = ai.applicationInfo;
11028                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11029                        mTopAction = Intent.ACTION_FACTORY_TEST;
11030                        mTopData = null;
11031                        mTopComponent = new ComponentName(app.packageName,
11032                                ai.name);
11033                    } else {
11034                        errorMsg = mContext.getResources().getText(
11035                                com.android.internal.R.string.factorytest_not_system);
11036                    }
11037                } else {
11038                    errorMsg = mContext.getResources().getText(
11039                            com.android.internal.R.string.factorytest_no_action);
11040                }
11041                if (errorMsg != null) {
11042                    mTopAction = null;
11043                    mTopData = null;
11044                    mTopComponent = null;
11045                    Message msg = Message.obtain();
11046                    msg.what = SHOW_FACTORY_ERROR_MSG;
11047                    msg.getData().putCharSequence("msg", errorMsg);
11048                    mHandler.sendMessage(msg);
11049                }
11050            }
11051        }
11052
11053        retrieveSettings();
11054        loadResourcesOnSystemReady();
11055
11056        synchronized (this) {
11057            readGrantedUriPermissionsLocked();
11058        }
11059
11060        if (goingCallback != null) goingCallback.run();
11061
11062        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11063                Integer.toString(mCurrentUserId), mCurrentUserId);
11064        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11065                Integer.toString(mCurrentUserId), mCurrentUserId);
11066        mSystemServiceManager.startUser(mCurrentUserId);
11067
11068        synchronized (this) {
11069            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11070                try {
11071                    List apps = AppGlobals.getPackageManager().
11072                        getPersistentApplications(STOCK_PM_FLAGS);
11073                    if (apps != null) {
11074                        int N = apps.size();
11075                        int i;
11076                        for (i=0; i<N; i++) {
11077                            ApplicationInfo info
11078                                = (ApplicationInfo)apps.get(i);
11079                            if (info != null &&
11080                                    !info.packageName.equals("android")) {
11081                                addAppLocked(info, false, null /* ABI override */);
11082                            }
11083                        }
11084                    }
11085                } catch (RemoteException ex) {
11086                    // pm is in same process, this will never happen.
11087                }
11088            }
11089
11090            // Start up initial activity.
11091            mBooting = true;
11092            startHomeActivityLocked(mCurrentUserId, "systemReady");
11093
11094            try {
11095                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11096                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11097                            + " data partition or your device will be unstable.");
11098                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11099                }
11100            } catch (RemoteException e) {
11101            }
11102
11103            if (!Build.isBuildConsistent()) {
11104                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11105                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11106            }
11107
11108            long ident = Binder.clearCallingIdentity();
11109            try {
11110                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11111                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11112                        | Intent.FLAG_RECEIVER_FOREGROUND);
11113                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11114                broadcastIntentLocked(null, null, intent,
11115                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11116                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11117                intent = new Intent(Intent.ACTION_USER_STARTING);
11118                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11119                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11120                broadcastIntentLocked(null, null, intent,
11121                        null, new IIntentReceiver.Stub() {
11122                            @Override
11123                            public void performReceive(Intent intent, int resultCode, String data,
11124                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11125                                    throws RemoteException {
11126                            }
11127                        }, 0, null, null,
11128                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11129                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11130            } catch (Throwable t) {
11131                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11132            } finally {
11133                Binder.restoreCallingIdentity(ident);
11134            }
11135            mStackSupervisor.resumeTopActivitiesLocked();
11136            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11137        }
11138    }
11139
11140    private boolean makeAppCrashingLocked(ProcessRecord app,
11141            String shortMsg, String longMsg, String stackTrace) {
11142        app.crashing = true;
11143        app.crashingReport = generateProcessError(app,
11144                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11145        startAppProblemLocked(app);
11146        app.stopFreezingAllLocked();
11147        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11148    }
11149
11150    private void makeAppNotRespondingLocked(ProcessRecord app,
11151            String activity, String shortMsg, String longMsg) {
11152        app.notResponding = true;
11153        app.notRespondingReport = generateProcessError(app,
11154                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11155                activity, shortMsg, longMsg, null);
11156        startAppProblemLocked(app);
11157        app.stopFreezingAllLocked();
11158    }
11159
11160    /**
11161     * Generate a process error record, suitable for attachment to a ProcessRecord.
11162     *
11163     * @param app The ProcessRecord in which the error occurred.
11164     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11165     *                      ActivityManager.AppErrorStateInfo
11166     * @param activity The activity associated with the crash, if known.
11167     * @param shortMsg Short message describing the crash.
11168     * @param longMsg Long message describing the crash.
11169     * @param stackTrace Full crash stack trace, may be null.
11170     *
11171     * @return Returns a fully-formed AppErrorStateInfo record.
11172     */
11173    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11174            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11175        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11176
11177        report.condition = condition;
11178        report.processName = app.processName;
11179        report.pid = app.pid;
11180        report.uid = app.info.uid;
11181        report.tag = activity;
11182        report.shortMsg = shortMsg;
11183        report.longMsg = longMsg;
11184        report.stackTrace = stackTrace;
11185
11186        return report;
11187    }
11188
11189    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11190        synchronized (this) {
11191            app.crashing = false;
11192            app.crashingReport = null;
11193            app.notResponding = false;
11194            app.notRespondingReport = null;
11195            if (app.anrDialog == fromDialog) {
11196                app.anrDialog = null;
11197            }
11198            if (app.waitDialog == fromDialog) {
11199                app.waitDialog = null;
11200            }
11201            if (app.pid > 0 && app.pid != MY_PID) {
11202                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11203                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11204                app.kill("user request after error", true);
11205            }
11206        }
11207    }
11208
11209    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11210            String shortMsg, String longMsg, String stackTrace) {
11211        long now = SystemClock.uptimeMillis();
11212
11213        Long crashTime;
11214        if (!app.isolated) {
11215            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11216        } else {
11217            crashTime = null;
11218        }
11219        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11220            // This process loses!
11221            Slog.w(TAG, "Process " + app.info.processName
11222                    + " has crashed too many times: killing!");
11223            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11224                    app.userId, app.info.processName, app.uid);
11225            mStackSupervisor.handleAppCrashLocked(app);
11226            if (!app.persistent) {
11227                // We don't want to start this process again until the user
11228                // explicitly does so...  but for persistent process, we really
11229                // need to keep it running.  If a persistent process is actually
11230                // repeatedly crashing, then badness for everyone.
11231                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11232                        app.info.processName);
11233                if (!app.isolated) {
11234                    // XXX We don't have a way to mark isolated processes
11235                    // as bad, since they don't have a peristent identity.
11236                    mBadProcesses.put(app.info.processName, app.uid,
11237                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11238                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11239                }
11240                app.bad = true;
11241                app.removed = true;
11242                // Don't let services in this process be restarted and potentially
11243                // annoy the user repeatedly.  Unless it is persistent, since those
11244                // processes run critical code.
11245                removeProcessLocked(app, false, false, "crash");
11246                mStackSupervisor.resumeTopActivitiesLocked();
11247                return false;
11248            }
11249            mStackSupervisor.resumeTopActivitiesLocked();
11250        } else {
11251            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11252        }
11253
11254        // Bump up the crash count of any services currently running in the proc.
11255        for (int i=app.services.size()-1; i>=0; i--) {
11256            // Any services running in the application need to be placed
11257            // back in the pending list.
11258            ServiceRecord sr = app.services.valueAt(i);
11259            sr.crashCount++;
11260        }
11261
11262        // If the crashing process is what we consider to be the "home process" and it has been
11263        // replaced by a third-party app, clear the package preferred activities from packages
11264        // with a home activity running in the process to prevent a repeatedly crashing app
11265        // from blocking the user to manually clear the list.
11266        final ArrayList<ActivityRecord> activities = app.activities;
11267        if (app == mHomeProcess && activities.size() > 0
11268                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11269            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11270                final ActivityRecord r = activities.get(activityNdx);
11271                if (r.isHomeActivity()) {
11272                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11273                    try {
11274                        ActivityThread.getPackageManager()
11275                                .clearPackagePreferredActivities(r.packageName);
11276                    } catch (RemoteException c) {
11277                        // pm is in same process, this will never happen.
11278                    }
11279                }
11280            }
11281        }
11282
11283        if (!app.isolated) {
11284            // XXX Can't keep track of crash times for isolated processes,
11285            // because they don't have a perisistent identity.
11286            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11287        }
11288
11289        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11290        return true;
11291    }
11292
11293    void startAppProblemLocked(ProcessRecord app) {
11294        // If this app is not running under the current user, then we
11295        // can't give it a report button because that would require
11296        // launching the report UI under a different user.
11297        app.errorReportReceiver = null;
11298
11299        for (int userId : mCurrentProfileIds) {
11300            if (app.userId == userId) {
11301                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11302                        mContext, app.info.packageName, app.info.flags);
11303            }
11304        }
11305        skipCurrentReceiverLocked(app);
11306    }
11307
11308    void skipCurrentReceiverLocked(ProcessRecord app) {
11309        for (BroadcastQueue queue : mBroadcastQueues) {
11310            queue.skipCurrentReceiverLocked(app);
11311        }
11312    }
11313
11314    /**
11315     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11316     * The application process will exit immediately after this call returns.
11317     * @param app object of the crashing app, null for the system server
11318     * @param crashInfo describing the exception
11319     */
11320    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11321        ProcessRecord r = findAppProcess(app, "Crash");
11322        final String processName = app == null ? "system_server"
11323                : (r == null ? "unknown" : r.processName);
11324
11325        handleApplicationCrashInner("crash", r, processName, crashInfo);
11326    }
11327
11328    /* Native crash reporting uses this inner version because it needs to be somewhat
11329     * decoupled from the AM-managed cleanup lifecycle
11330     */
11331    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11332            ApplicationErrorReport.CrashInfo crashInfo) {
11333        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11334                UserHandle.getUserId(Binder.getCallingUid()), processName,
11335                r == null ? -1 : r.info.flags,
11336                crashInfo.exceptionClassName,
11337                crashInfo.exceptionMessage,
11338                crashInfo.throwFileName,
11339                crashInfo.throwLineNumber);
11340
11341        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11342
11343        crashApplication(r, crashInfo);
11344    }
11345
11346    public void handleApplicationStrictModeViolation(
11347            IBinder app,
11348            int violationMask,
11349            StrictMode.ViolationInfo info) {
11350        ProcessRecord r = findAppProcess(app, "StrictMode");
11351        if (r == null) {
11352            return;
11353        }
11354
11355        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11356            Integer stackFingerprint = info.hashCode();
11357            boolean logIt = true;
11358            synchronized (mAlreadyLoggedViolatedStacks) {
11359                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11360                    logIt = false;
11361                    // TODO: sub-sample into EventLog for these, with
11362                    // the info.durationMillis?  Then we'd get
11363                    // the relative pain numbers, without logging all
11364                    // the stack traces repeatedly.  We'd want to do
11365                    // likewise in the client code, which also does
11366                    // dup suppression, before the Binder call.
11367                } else {
11368                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11369                        mAlreadyLoggedViolatedStacks.clear();
11370                    }
11371                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11372                }
11373            }
11374            if (logIt) {
11375                logStrictModeViolationToDropBox(r, info);
11376            }
11377        }
11378
11379        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11380            AppErrorResult result = new AppErrorResult();
11381            synchronized (this) {
11382                final long origId = Binder.clearCallingIdentity();
11383
11384                Message msg = Message.obtain();
11385                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11386                HashMap<String, Object> data = new HashMap<String, Object>();
11387                data.put("result", result);
11388                data.put("app", r);
11389                data.put("violationMask", violationMask);
11390                data.put("info", info);
11391                msg.obj = data;
11392                mHandler.sendMessage(msg);
11393
11394                Binder.restoreCallingIdentity(origId);
11395            }
11396            int res = result.get();
11397            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11398        }
11399    }
11400
11401    // Depending on the policy in effect, there could be a bunch of
11402    // these in quick succession so we try to batch these together to
11403    // minimize disk writes, number of dropbox entries, and maximize
11404    // compression, by having more fewer, larger records.
11405    private void logStrictModeViolationToDropBox(
11406            ProcessRecord process,
11407            StrictMode.ViolationInfo info) {
11408        if (info == null) {
11409            return;
11410        }
11411        final boolean isSystemApp = process == null ||
11412                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11413                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11414        final String processName = process == null ? "unknown" : process.processName;
11415        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11416        final DropBoxManager dbox = (DropBoxManager)
11417                mContext.getSystemService(Context.DROPBOX_SERVICE);
11418
11419        // Exit early if the dropbox isn't configured to accept this report type.
11420        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11421
11422        boolean bufferWasEmpty;
11423        boolean needsFlush;
11424        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11425        synchronized (sb) {
11426            bufferWasEmpty = sb.length() == 0;
11427            appendDropBoxProcessHeaders(process, processName, sb);
11428            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11429            sb.append("System-App: ").append(isSystemApp).append("\n");
11430            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11431            if (info.violationNumThisLoop != 0) {
11432                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11433            }
11434            if (info.numAnimationsRunning != 0) {
11435                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11436            }
11437            if (info.broadcastIntentAction != null) {
11438                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11439            }
11440            if (info.durationMillis != -1) {
11441                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11442            }
11443            if (info.numInstances != -1) {
11444                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11445            }
11446            if (info.tags != null) {
11447                for (String tag : info.tags) {
11448                    sb.append("Span-Tag: ").append(tag).append("\n");
11449                }
11450            }
11451            sb.append("\n");
11452            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11453                sb.append(info.crashInfo.stackTrace);
11454                sb.append("\n");
11455            }
11456            if (info.message != null) {
11457                sb.append(info.message);
11458                sb.append("\n");
11459            }
11460
11461            // Only buffer up to ~64k.  Various logging bits truncate
11462            // things at 128k.
11463            needsFlush = (sb.length() > 64 * 1024);
11464        }
11465
11466        // Flush immediately if the buffer's grown too large, or this
11467        // is a non-system app.  Non-system apps are isolated with a
11468        // different tag & policy and not batched.
11469        //
11470        // Batching is useful during internal testing with
11471        // StrictMode settings turned up high.  Without batching,
11472        // thousands of separate files could be created on boot.
11473        if (!isSystemApp || needsFlush) {
11474            new Thread("Error dump: " + dropboxTag) {
11475                @Override
11476                public void run() {
11477                    String report;
11478                    synchronized (sb) {
11479                        report = sb.toString();
11480                        sb.delete(0, sb.length());
11481                        sb.trimToSize();
11482                    }
11483                    if (report.length() != 0) {
11484                        dbox.addText(dropboxTag, report);
11485                    }
11486                }
11487            }.start();
11488            return;
11489        }
11490
11491        // System app batching:
11492        if (!bufferWasEmpty) {
11493            // An existing dropbox-writing thread is outstanding, so
11494            // we don't need to start it up.  The existing thread will
11495            // catch the buffer appends we just did.
11496            return;
11497        }
11498
11499        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11500        // (After this point, we shouldn't access AMS internal data structures.)
11501        new Thread("Error dump: " + dropboxTag) {
11502            @Override
11503            public void run() {
11504                // 5 second sleep to let stacks arrive and be batched together
11505                try {
11506                    Thread.sleep(5000);  // 5 seconds
11507                } catch (InterruptedException e) {}
11508
11509                String errorReport;
11510                synchronized (mStrictModeBuffer) {
11511                    errorReport = mStrictModeBuffer.toString();
11512                    if (errorReport.length() == 0) {
11513                        return;
11514                    }
11515                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11516                    mStrictModeBuffer.trimToSize();
11517                }
11518                dbox.addText(dropboxTag, errorReport);
11519            }
11520        }.start();
11521    }
11522
11523    /**
11524     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11525     * @param app object of the crashing app, null for the system server
11526     * @param tag reported by the caller
11527     * @param system whether this wtf is coming from the system
11528     * @param crashInfo describing the context of the error
11529     * @return true if the process should exit immediately (WTF is fatal)
11530     */
11531    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11532            final ApplicationErrorReport.CrashInfo crashInfo) {
11533        final int callingUid = Binder.getCallingUid();
11534        final int callingPid = Binder.getCallingPid();
11535
11536        if (system) {
11537            // If this is coming from the system, we could very well have low-level
11538            // system locks held, so we want to do this all asynchronously.  And we
11539            // never want this to become fatal, so there is that too.
11540            mHandler.post(new Runnable() {
11541                @Override public void run() {
11542                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11543                }
11544            });
11545            return false;
11546        }
11547
11548        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11549                crashInfo);
11550
11551        if (r != null && r.pid != Process.myPid() &&
11552                Settings.Global.getInt(mContext.getContentResolver(),
11553                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11554            crashApplication(r, crashInfo);
11555            return true;
11556        } else {
11557            return false;
11558        }
11559    }
11560
11561    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11562            final ApplicationErrorReport.CrashInfo crashInfo) {
11563        final ProcessRecord r = findAppProcess(app, "WTF");
11564        final String processName = app == null ? "system_server"
11565                : (r == null ? "unknown" : r.processName);
11566
11567        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11568                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11569
11570        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11571
11572        return r;
11573    }
11574
11575    /**
11576     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11577     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11578     */
11579    private ProcessRecord findAppProcess(IBinder app, String reason) {
11580        if (app == null) {
11581            return null;
11582        }
11583
11584        synchronized (this) {
11585            final int NP = mProcessNames.getMap().size();
11586            for (int ip=0; ip<NP; ip++) {
11587                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11588                final int NA = apps.size();
11589                for (int ia=0; ia<NA; ia++) {
11590                    ProcessRecord p = apps.valueAt(ia);
11591                    if (p.thread != null && p.thread.asBinder() == app) {
11592                        return p;
11593                    }
11594                }
11595            }
11596
11597            Slog.w(TAG, "Can't find mystery application for " + reason
11598                    + " from pid=" + Binder.getCallingPid()
11599                    + " uid=" + Binder.getCallingUid() + ": " + app);
11600            return null;
11601        }
11602    }
11603
11604    /**
11605     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11606     * to append various headers to the dropbox log text.
11607     */
11608    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11609            StringBuilder sb) {
11610        // Watchdog thread ends up invoking this function (with
11611        // a null ProcessRecord) to add the stack file to dropbox.
11612        // Do not acquire a lock on this (am) in such cases, as it
11613        // could cause a potential deadlock, if and when watchdog
11614        // is invoked due to unavailability of lock on am and it
11615        // would prevent watchdog from killing system_server.
11616        if (process == null) {
11617            sb.append("Process: ").append(processName).append("\n");
11618            return;
11619        }
11620        // Note: ProcessRecord 'process' is guarded by the service
11621        // instance.  (notably process.pkgList, which could otherwise change
11622        // concurrently during execution of this method)
11623        synchronized (this) {
11624            sb.append("Process: ").append(processName).append("\n");
11625            int flags = process.info.flags;
11626            IPackageManager pm = AppGlobals.getPackageManager();
11627            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11628            for (int ip=0; ip<process.pkgList.size(); ip++) {
11629                String pkg = process.pkgList.keyAt(ip);
11630                sb.append("Package: ").append(pkg);
11631                try {
11632                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11633                    if (pi != null) {
11634                        sb.append(" v").append(pi.versionCode);
11635                        if (pi.versionName != null) {
11636                            sb.append(" (").append(pi.versionName).append(")");
11637                        }
11638                    }
11639                } catch (RemoteException e) {
11640                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11641                }
11642                sb.append("\n");
11643            }
11644        }
11645    }
11646
11647    private static String processClass(ProcessRecord process) {
11648        if (process == null || process.pid == MY_PID) {
11649            return "system_server";
11650        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11651            return "system_app";
11652        } else {
11653            return "data_app";
11654        }
11655    }
11656
11657    /**
11658     * Write a description of an error (crash, WTF, ANR) to the drop box.
11659     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11660     * @param process which caused the error, null means the system server
11661     * @param activity which triggered the error, null if unknown
11662     * @param parent activity related to the error, null if unknown
11663     * @param subject line related to the error, null if absent
11664     * @param report in long form describing the error, null if absent
11665     * @param logFile to include in the report, null if none
11666     * @param crashInfo giving an application stack trace, null if absent
11667     */
11668    public void addErrorToDropBox(String eventType,
11669            ProcessRecord process, String processName, ActivityRecord activity,
11670            ActivityRecord parent, String subject,
11671            final String report, final File logFile,
11672            final ApplicationErrorReport.CrashInfo crashInfo) {
11673        // NOTE -- this must never acquire the ActivityManagerService lock,
11674        // otherwise the watchdog may be prevented from resetting the system.
11675
11676        final String dropboxTag = processClass(process) + "_" + eventType;
11677        final DropBoxManager dbox = (DropBoxManager)
11678                mContext.getSystemService(Context.DROPBOX_SERVICE);
11679
11680        // Exit early if the dropbox isn't configured to accept this report type.
11681        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11682
11683        final StringBuilder sb = new StringBuilder(1024);
11684        appendDropBoxProcessHeaders(process, processName, sb);
11685        if (activity != null) {
11686            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11687        }
11688        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11689            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11690        }
11691        if (parent != null && parent != activity) {
11692            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11693        }
11694        if (subject != null) {
11695            sb.append("Subject: ").append(subject).append("\n");
11696        }
11697        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11698        if (Debug.isDebuggerConnected()) {
11699            sb.append("Debugger: Connected\n");
11700        }
11701        sb.append("\n");
11702
11703        // Do the rest in a worker thread to avoid blocking the caller on I/O
11704        // (After this point, we shouldn't access AMS internal data structures.)
11705        Thread worker = new Thread("Error dump: " + dropboxTag) {
11706            @Override
11707            public void run() {
11708                if (report != null) {
11709                    sb.append(report);
11710                }
11711                if (logFile != null) {
11712                    try {
11713                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11714                                    "\n\n[[TRUNCATED]]"));
11715                    } catch (IOException e) {
11716                        Slog.e(TAG, "Error reading " + logFile, e);
11717                    }
11718                }
11719                if (crashInfo != null && crashInfo.stackTrace != null) {
11720                    sb.append(crashInfo.stackTrace);
11721                }
11722
11723                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11724                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11725                if (lines > 0) {
11726                    sb.append("\n");
11727
11728                    // Merge several logcat streams, and take the last N lines
11729                    InputStreamReader input = null;
11730                    try {
11731                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11732                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11733                                "-b", "crash",
11734                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11735
11736                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11737                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11738                        input = new InputStreamReader(logcat.getInputStream());
11739
11740                        int num;
11741                        char[] buf = new char[8192];
11742                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11743                    } catch (IOException e) {
11744                        Slog.e(TAG, "Error running logcat", e);
11745                    } finally {
11746                        if (input != null) try { input.close(); } catch (IOException e) {}
11747                    }
11748                }
11749
11750                dbox.addText(dropboxTag, sb.toString());
11751            }
11752        };
11753
11754        if (process == null) {
11755            // If process is null, we are being called from some internal code
11756            // and may be about to die -- run this synchronously.
11757            worker.run();
11758        } else {
11759            worker.start();
11760        }
11761    }
11762
11763    /**
11764     * Bring up the "unexpected error" dialog box for a crashing app.
11765     * Deal with edge cases (intercepts from instrumented applications,
11766     * ActivityController, error intent receivers, that sort of thing).
11767     * @param r the application crashing
11768     * @param crashInfo describing the failure
11769     */
11770    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11771        long timeMillis = System.currentTimeMillis();
11772        String shortMsg = crashInfo.exceptionClassName;
11773        String longMsg = crashInfo.exceptionMessage;
11774        String stackTrace = crashInfo.stackTrace;
11775        if (shortMsg != null && longMsg != null) {
11776            longMsg = shortMsg + ": " + longMsg;
11777        } else if (shortMsg != null) {
11778            longMsg = shortMsg;
11779        }
11780
11781        AppErrorResult result = new AppErrorResult();
11782        synchronized (this) {
11783            if (mController != null) {
11784                try {
11785                    String name = r != null ? r.processName : null;
11786                    int pid = r != null ? r.pid : Binder.getCallingPid();
11787                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11788                    if (!mController.appCrashed(name, pid,
11789                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11790                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11791                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11792                            Slog.w(TAG, "Skip killing native crashed app " + name
11793                                    + "(" + pid + ") during testing");
11794                        } else {
11795                            Slog.w(TAG, "Force-killing crashed app " + name
11796                                    + " at watcher's request");
11797                            if (r != null) {
11798                                r.kill("crash", true);
11799                            } else {
11800                                // Huh.
11801                                Process.killProcess(pid);
11802                                Process.killProcessGroup(uid, pid);
11803                            }
11804                        }
11805                        return;
11806                    }
11807                } catch (RemoteException e) {
11808                    mController = null;
11809                    Watchdog.getInstance().setActivityController(null);
11810                }
11811            }
11812
11813            final long origId = Binder.clearCallingIdentity();
11814
11815            // If this process is running instrumentation, finish it.
11816            if (r != null && r.instrumentationClass != null) {
11817                Slog.w(TAG, "Error in app " + r.processName
11818                      + " running instrumentation " + r.instrumentationClass + ":");
11819                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11820                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11821                Bundle info = new Bundle();
11822                info.putString("shortMsg", shortMsg);
11823                info.putString("longMsg", longMsg);
11824                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11825                Binder.restoreCallingIdentity(origId);
11826                return;
11827            }
11828
11829            // Log crash in battery stats.
11830            if (r != null) {
11831                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
11832            }
11833
11834            // If we can't identify the process or it's already exceeded its crash quota,
11835            // quit right away without showing a crash dialog.
11836            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11837                Binder.restoreCallingIdentity(origId);
11838                return;
11839            }
11840
11841            Message msg = Message.obtain();
11842            msg.what = SHOW_ERROR_MSG;
11843            HashMap data = new HashMap();
11844            data.put("result", result);
11845            data.put("app", r);
11846            msg.obj = data;
11847            mHandler.sendMessage(msg);
11848
11849            Binder.restoreCallingIdentity(origId);
11850        }
11851
11852        int res = result.get();
11853
11854        Intent appErrorIntent = null;
11855        synchronized (this) {
11856            if (r != null && !r.isolated) {
11857                // XXX Can't keep track of crash time for isolated processes,
11858                // since they don't have a persistent identity.
11859                mProcessCrashTimes.put(r.info.processName, r.uid,
11860                        SystemClock.uptimeMillis());
11861            }
11862            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11863                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11864            }
11865        }
11866
11867        if (appErrorIntent != null) {
11868            try {
11869                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11870            } catch (ActivityNotFoundException e) {
11871                Slog.w(TAG, "bug report receiver dissappeared", e);
11872            }
11873        }
11874    }
11875
11876    Intent createAppErrorIntentLocked(ProcessRecord r,
11877            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11878        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11879        if (report == null) {
11880            return null;
11881        }
11882        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11883        result.setComponent(r.errorReportReceiver);
11884        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11885        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11886        return result;
11887    }
11888
11889    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11890            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11891        if (r.errorReportReceiver == null) {
11892            return null;
11893        }
11894
11895        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11896            return null;
11897        }
11898
11899        ApplicationErrorReport report = new ApplicationErrorReport();
11900        report.packageName = r.info.packageName;
11901        report.installerPackageName = r.errorReportReceiver.getPackageName();
11902        report.processName = r.processName;
11903        report.time = timeMillis;
11904        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11905
11906        if (r.crashing || r.forceCrashReport) {
11907            report.type = ApplicationErrorReport.TYPE_CRASH;
11908            report.crashInfo = crashInfo;
11909        } else if (r.notResponding) {
11910            report.type = ApplicationErrorReport.TYPE_ANR;
11911            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11912
11913            report.anrInfo.activity = r.notRespondingReport.tag;
11914            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11915            report.anrInfo.info = r.notRespondingReport.longMsg;
11916        }
11917
11918        return report;
11919    }
11920
11921    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11922        enforceNotIsolatedCaller("getProcessesInErrorState");
11923        // assume our apps are happy - lazy create the list
11924        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11925
11926        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11927                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11928        int userId = UserHandle.getUserId(Binder.getCallingUid());
11929
11930        synchronized (this) {
11931
11932            // iterate across all processes
11933            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11934                ProcessRecord app = mLruProcesses.get(i);
11935                if (!allUsers && app.userId != userId) {
11936                    continue;
11937                }
11938                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11939                    // This one's in trouble, so we'll generate a report for it
11940                    // crashes are higher priority (in case there's a crash *and* an anr)
11941                    ActivityManager.ProcessErrorStateInfo report = null;
11942                    if (app.crashing) {
11943                        report = app.crashingReport;
11944                    } else if (app.notResponding) {
11945                        report = app.notRespondingReport;
11946                    }
11947
11948                    if (report != null) {
11949                        if (errList == null) {
11950                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11951                        }
11952                        errList.add(report);
11953                    } else {
11954                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11955                                " crashing = " + app.crashing +
11956                                " notResponding = " + app.notResponding);
11957                    }
11958                }
11959            }
11960        }
11961
11962        return errList;
11963    }
11964
11965    static int procStateToImportance(int procState, int memAdj,
11966            ActivityManager.RunningAppProcessInfo currApp) {
11967        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11968        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11969            currApp.lru = memAdj;
11970        } else {
11971            currApp.lru = 0;
11972        }
11973        return imp;
11974    }
11975
11976    private void fillInProcMemInfo(ProcessRecord app,
11977            ActivityManager.RunningAppProcessInfo outInfo) {
11978        outInfo.pid = app.pid;
11979        outInfo.uid = app.info.uid;
11980        if (mHeavyWeightProcess == app) {
11981            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11982        }
11983        if (app.persistent) {
11984            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11985        }
11986        if (app.activities.size() > 0) {
11987            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11988        }
11989        outInfo.lastTrimLevel = app.trimMemoryLevel;
11990        int adj = app.curAdj;
11991        int procState = app.curProcState;
11992        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11993        outInfo.importanceReasonCode = app.adjTypeCode;
11994        outInfo.processState = app.curProcState;
11995    }
11996
11997    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11998        enforceNotIsolatedCaller("getRunningAppProcesses");
11999        // Lazy instantiation of list
12000        List<ActivityManager.RunningAppProcessInfo> runList = null;
12001        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12002                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12003        int userId = UserHandle.getUserId(Binder.getCallingUid());
12004        synchronized (this) {
12005            // Iterate across all processes
12006            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12007                ProcessRecord app = mLruProcesses.get(i);
12008                if (!allUsers && app.userId != userId) {
12009                    continue;
12010                }
12011                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12012                    // Generate process state info for running application
12013                    ActivityManager.RunningAppProcessInfo currApp =
12014                        new ActivityManager.RunningAppProcessInfo(app.processName,
12015                                app.pid, app.getPackageList());
12016                    fillInProcMemInfo(app, currApp);
12017                    if (app.adjSource instanceof ProcessRecord) {
12018                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12019                        currApp.importanceReasonImportance =
12020                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12021                                        app.adjSourceProcState);
12022                    } else if (app.adjSource instanceof ActivityRecord) {
12023                        ActivityRecord r = (ActivityRecord)app.adjSource;
12024                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12025                    }
12026                    if (app.adjTarget instanceof ComponentName) {
12027                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12028                    }
12029                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12030                    //        + " lru=" + currApp.lru);
12031                    if (runList == null) {
12032                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12033                    }
12034                    runList.add(currApp);
12035                }
12036            }
12037        }
12038        return runList;
12039    }
12040
12041    public List<ApplicationInfo> getRunningExternalApplications() {
12042        enforceNotIsolatedCaller("getRunningExternalApplications");
12043        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12044        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12045        if (runningApps != null && runningApps.size() > 0) {
12046            Set<String> extList = new HashSet<String>();
12047            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12048                if (app.pkgList != null) {
12049                    for (String pkg : app.pkgList) {
12050                        extList.add(pkg);
12051                    }
12052                }
12053            }
12054            IPackageManager pm = AppGlobals.getPackageManager();
12055            for (String pkg : extList) {
12056                try {
12057                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12058                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12059                        retList.add(info);
12060                    }
12061                } catch (RemoteException e) {
12062                }
12063            }
12064        }
12065        return retList;
12066    }
12067
12068    @Override
12069    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12070        enforceNotIsolatedCaller("getMyMemoryState");
12071        synchronized (this) {
12072            ProcessRecord proc;
12073            synchronized (mPidsSelfLocked) {
12074                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12075            }
12076            fillInProcMemInfo(proc, outInfo);
12077        }
12078    }
12079
12080    @Override
12081    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12082        if (checkCallingPermission(android.Manifest.permission.DUMP)
12083                != PackageManager.PERMISSION_GRANTED) {
12084            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12085                    + Binder.getCallingPid()
12086                    + ", uid=" + Binder.getCallingUid()
12087                    + " without permission "
12088                    + android.Manifest.permission.DUMP);
12089            return;
12090        }
12091
12092        boolean dumpAll = false;
12093        boolean dumpClient = false;
12094        String dumpPackage = null;
12095
12096        int opti = 0;
12097        while (opti < args.length) {
12098            String opt = args[opti];
12099            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12100                break;
12101            }
12102            opti++;
12103            if ("-a".equals(opt)) {
12104                dumpAll = true;
12105            } else if ("-c".equals(opt)) {
12106                dumpClient = true;
12107            } else if ("-p".equals(opt)) {
12108                if (opti < args.length) {
12109                    dumpPackage = args[opti];
12110                    opti++;
12111                } else {
12112                    pw.println("Error: -p option requires package argument");
12113                    return;
12114                }
12115                dumpClient = true;
12116            } else if ("-h".equals(opt)) {
12117                pw.println("Activity manager dump options:");
12118                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12119                pw.println("  cmd may be one of:");
12120                pw.println("    a[ctivities]: activity stack state");
12121                pw.println("    r[recents]: recent activities state");
12122                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12123                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12124                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12125                pw.println("    o[om]: out of memory management");
12126                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12127                pw.println("    provider [COMP_SPEC]: provider client-side state");
12128                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12129                pw.println("    as[sociations]: tracked app associations");
12130                pw.println("    service [COMP_SPEC]: service client-side state");
12131                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12132                pw.println("    all: dump all activities");
12133                pw.println("    top: dump the top activity");
12134                pw.println("    write: write all pending state to storage");
12135                pw.println("    track-associations: enable association tracking");
12136                pw.println("    untrack-associations: disable and clear association tracking");
12137                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12138                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12139                pw.println("    a partial substring in a component name, a");
12140                pw.println("    hex object identifier.");
12141                pw.println("  -a: include all available server state.");
12142                pw.println("  -c: include client state.");
12143                pw.println("  -p: limit output to given package.");
12144                return;
12145            } else {
12146                pw.println("Unknown argument: " + opt + "; use -h for help");
12147            }
12148        }
12149
12150        long origId = Binder.clearCallingIdentity();
12151        boolean more = false;
12152        // Is the caller requesting to dump a particular piece of data?
12153        if (opti < args.length) {
12154            String cmd = args[opti];
12155            opti++;
12156            if ("activities".equals(cmd) || "a".equals(cmd)) {
12157                synchronized (this) {
12158                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12159                }
12160            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12161                synchronized (this) {
12162                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12163                }
12164            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12165                String[] newArgs;
12166                String name;
12167                if (opti >= args.length) {
12168                    name = null;
12169                    newArgs = EMPTY_STRING_ARRAY;
12170                } else {
12171                    dumpPackage = args[opti];
12172                    opti++;
12173                    newArgs = new String[args.length - opti];
12174                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12175                            args.length - opti);
12176                }
12177                synchronized (this) {
12178                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12179                }
12180            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12181                String[] newArgs;
12182                String name;
12183                if (opti >= args.length) {
12184                    name = null;
12185                    newArgs = EMPTY_STRING_ARRAY;
12186                } else {
12187                    dumpPackage = args[opti];
12188                    opti++;
12189                    newArgs = new String[args.length - opti];
12190                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12191                            args.length - opti);
12192                }
12193                synchronized (this) {
12194                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12195                }
12196            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12197                String[] newArgs;
12198                String name;
12199                if (opti >= args.length) {
12200                    name = null;
12201                    newArgs = EMPTY_STRING_ARRAY;
12202                } else {
12203                    dumpPackage = args[opti];
12204                    opti++;
12205                    newArgs = new String[args.length - opti];
12206                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12207                            args.length - opti);
12208                }
12209                synchronized (this) {
12210                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12211                }
12212            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12213                synchronized (this) {
12214                    dumpOomLocked(fd, pw, args, opti, true);
12215                }
12216            } else if ("provider".equals(cmd)) {
12217                String[] newArgs;
12218                String name;
12219                if (opti >= args.length) {
12220                    name = null;
12221                    newArgs = EMPTY_STRING_ARRAY;
12222                } else {
12223                    name = args[opti];
12224                    opti++;
12225                    newArgs = new String[args.length - opti];
12226                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12227                }
12228                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12229                    pw.println("No providers match: " + name);
12230                    pw.println("Use -h for help.");
12231                }
12232            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12233                synchronized (this) {
12234                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12235                }
12236            } else if ("service".equals(cmd)) {
12237                String[] newArgs;
12238                String name;
12239                if (opti >= args.length) {
12240                    name = null;
12241                    newArgs = EMPTY_STRING_ARRAY;
12242                } else {
12243                    name = args[opti];
12244                    opti++;
12245                    newArgs = new String[args.length - opti];
12246                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12247                            args.length - opti);
12248                }
12249                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12250                    pw.println("No services match: " + name);
12251                    pw.println("Use -h for help.");
12252                }
12253            } else if ("package".equals(cmd)) {
12254                String[] newArgs;
12255                if (opti >= args.length) {
12256                    pw.println("package: no package name specified");
12257                    pw.println("Use -h for help.");
12258                } else {
12259                    dumpPackage = args[opti];
12260                    opti++;
12261                    newArgs = new String[args.length - opti];
12262                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12263                            args.length - opti);
12264                    args = newArgs;
12265                    opti = 0;
12266                    more = true;
12267                }
12268            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12269                synchronized (this) {
12270                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12271                }
12272            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12273                synchronized (this) {
12274                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12275                }
12276            } else if ("write".equals(cmd)) {
12277                mTaskPersister.flush();
12278                pw.println("All tasks persisted.");
12279                return;
12280            } else if ("track-associations".equals(cmd)) {
12281                synchronized (this) {
12282                    if (!mTrackingAssociations) {
12283                        mTrackingAssociations = true;
12284                        pw.println("Association tracking started.");
12285                    } else {
12286                        pw.println("Association tracking already enabled.");
12287                    }
12288                }
12289                return;
12290            } else if ("untrack-associations".equals(cmd)) {
12291                synchronized (this) {
12292                    if (mTrackingAssociations) {
12293                        mTrackingAssociations = false;
12294                        mAssociations.clear();
12295                        pw.println("Association tracking stopped.");
12296                    } else {
12297                        pw.println("Association tracking not running.");
12298                    }
12299                }
12300                return;
12301            } else {
12302                // Dumping a single activity?
12303                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12304                    pw.println("Bad activity command, or no activities match: " + cmd);
12305                    pw.println("Use -h for help.");
12306                }
12307            }
12308            if (!more) {
12309                Binder.restoreCallingIdentity(origId);
12310                return;
12311            }
12312        }
12313
12314        // No piece of data specified, dump everything.
12315        synchronized (this) {
12316            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12317            pw.println();
12318            if (dumpAll) {
12319                pw.println("-------------------------------------------------------------------------------");
12320            }
12321            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12322            pw.println();
12323            if (dumpAll) {
12324                pw.println("-------------------------------------------------------------------------------");
12325            }
12326            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12327            pw.println();
12328            if (dumpAll) {
12329                pw.println("-------------------------------------------------------------------------------");
12330            }
12331            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12332            pw.println();
12333            if (dumpAll) {
12334                pw.println("-------------------------------------------------------------------------------");
12335            }
12336            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12337            pw.println();
12338            if (dumpAll) {
12339                pw.println("-------------------------------------------------------------------------------");
12340            }
12341            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12342            if (mAssociations.size() > 0) {
12343                pw.println();
12344                if (dumpAll) {
12345                    pw.println("-------------------------------------------------------------------------------");
12346                }
12347                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12348            }
12349            pw.println();
12350            if (dumpAll) {
12351                pw.println("-------------------------------------------------------------------------------");
12352            }
12353            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12354        }
12355        Binder.restoreCallingIdentity(origId);
12356    }
12357
12358    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12359            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12360        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12361
12362        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12363                dumpPackage);
12364        boolean needSep = printedAnything;
12365
12366        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12367                dumpPackage, needSep, "  mFocusedActivity: ");
12368        if (printed) {
12369            printedAnything = true;
12370            needSep = false;
12371        }
12372
12373        if (dumpPackage == null) {
12374            if (needSep) {
12375                pw.println();
12376            }
12377            needSep = true;
12378            printedAnything = true;
12379            mStackSupervisor.dump(pw, "  ");
12380        }
12381
12382        if (!printedAnything) {
12383            pw.println("  (nothing)");
12384        }
12385    }
12386
12387    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12388            int opti, boolean dumpAll, String dumpPackage) {
12389        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12390
12391        boolean printedAnything = false;
12392
12393        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12394            boolean printedHeader = false;
12395
12396            final int N = mRecentTasks.size();
12397            for (int i=0; i<N; i++) {
12398                TaskRecord tr = mRecentTasks.get(i);
12399                if (dumpPackage != null) {
12400                    if (tr.realActivity == null ||
12401                            !dumpPackage.equals(tr.realActivity)) {
12402                        continue;
12403                    }
12404                }
12405                if (!printedHeader) {
12406                    pw.println("  Recent tasks:");
12407                    printedHeader = true;
12408                    printedAnything = true;
12409                }
12410                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12411                        pw.println(tr);
12412                if (dumpAll) {
12413                    mRecentTasks.get(i).dump(pw, "    ");
12414                }
12415            }
12416        }
12417
12418        if (!printedAnything) {
12419            pw.println("  (nothing)");
12420        }
12421    }
12422
12423    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12424            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12425        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12426
12427        int dumpUid = 0;
12428        if (dumpPackage != null) {
12429            IPackageManager pm = AppGlobals.getPackageManager();
12430            try {
12431                dumpUid = pm.getPackageUid(dumpPackage, 0);
12432            } catch (RemoteException e) {
12433            }
12434        }
12435
12436        boolean printedAnything = false;
12437
12438        final long now = SystemClock.uptimeMillis();
12439
12440        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12441            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12442                    = mAssociations.valueAt(i1);
12443            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12444                SparseArray<ArrayMap<String, Association>> sourceUids
12445                        = targetComponents.valueAt(i2);
12446                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12447                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12448                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12449                        Association ass = sourceProcesses.valueAt(i4);
12450                        if (dumpPackage != null) {
12451                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12452                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12453                                continue;
12454                            }
12455                        }
12456                        printedAnything = true;
12457                        pw.print("  ");
12458                        pw.print(ass.mTargetProcess);
12459                        pw.print("/");
12460                        UserHandle.formatUid(pw, ass.mTargetUid);
12461                        pw.print(" <- ");
12462                        pw.print(ass.mSourceProcess);
12463                        pw.print("/");
12464                        UserHandle.formatUid(pw, ass.mSourceUid);
12465                        pw.println();
12466                        pw.print("    via ");
12467                        pw.print(ass.mTargetComponent.flattenToShortString());
12468                        pw.println();
12469                        pw.print("    ");
12470                        long dur = ass.mTime;
12471                        if (ass.mNesting > 0) {
12472                            dur += now - ass.mStartTime;
12473                        }
12474                        TimeUtils.formatDuration(dur, pw);
12475                        pw.print(" (");
12476                        pw.print(ass.mCount);
12477                        pw.println(" times)");
12478                        if (ass.mNesting > 0) {
12479                            pw.print("    ");
12480                            pw.print(" Currently active: ");
12481                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
12482                            pw.println();
12483                        }
12484                    }
12485                }
12486            }
12487
12488        }
12489
12490        if (!printedAnything) {
12491            pw.println("  (nothing)");
12492        }
12493    }
12494
12495    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12496            int opti, boolean dumpAll, String dumpPackage) {
12497        boolean needSep = false;
12498        boolean printedAnything = false;
12499        int numPers = 0;
12500
12501        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12502
12503        if (dumpAll) {
12504            final int NP = mProcessNames.getMap().size();
12505            for (int ip=0; ip<NP; ip++) {
12506                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12507                final int NA = procs.size();
12508                for (int ia=0; ia<NA; ia++) {
12509                    ProcessRecord r = procs.valueAt(ia);
12510                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12511                        continue;
12512                    }
12513                    if (!needSep) {
12514                        pw.println("  All known processes:");
12515                        needSep = true;
12516                        printedAnything = true;
12517                    }
12518                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12519                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12520                        pw.print(" "); pw.println(r);
12521                    r.dump(pw, "    ");
12522                    if (r.persistent) {
12523                        numPers++;
12524                    }
12525                }
12526            }
12527        }
12528
12529        if (mIsolatedProcesses.size() > 0) {
12530            boolean printed = false;
12531            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12532                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12533                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12534                    continue;
12535                }
12536                if (!printed) {
12537                    if (needSep) {
12538                        pw.println();
12539                    }
12540                    pw.println("  Isolated process list (sorted by uid):");
12541                    printedAnything = true;
12542                    printed = true;
12543                    needSep = true;
12544                }
12545                pw.println(String.format("%sIsolated #%2d: %s",
12546                        "    ", i, r.toString()));
12547            }
12548        }
12549
12550        if (mLruProcesses.size() > 0) {
12551            if (needSep) {
12552                pw.println();
12553            }
12554            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12555                    pw.print(" total, non-act at ");
12556                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12557                    pw.print(", non-svc at ");
12558                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12559                    pw.println("):");
12560            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12561            needSep = true;
12562            printedAnything = true;
12563        }
12564
12565        if (dumpAll || dumpPackage != null) {
12566            synchronized (mPidsSelfLocked) {
12567                boolean printed = false;
12568                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12569                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12570                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12571                        continue;
12572                    }
12573                    if (!printed) {
12574                        if (needSep) pw.println();
12575                        needSep = true;
12576                        pw.println("  PID mappings:");
12577                        printed = true;
12578                        printedAnything = true;
12579                    }
12580                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12581                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12582                }
12583            }
12584        }
12585
12586        if (mForegroundProcesses.size() > 0) {
12587            synchronized (mPidsSelfLocked) {
12588                boolean printed = false;
12589                for (int i=0; i<mForegroundProcesses.size(); i++) {
12590                    ProcessRecord r = mPidsSelfLocked.get(
12591                            mForegroundProcesses.valueAt(i).pid);
12592                    if (dumpPackage != null && (r == null
12593                            || !r.pkgList.containsKey(dumpPackage))) {
12594                        continue;
12595                    }
12596                    if (!printed) {
12597                        if (needSep) pw.println();
12598                        needSep = true;
12599                        pw.println("  Foreground Processes:");
12600                        printed = true;
12601                        printedAnything = true;
12602                    }
12603                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12604                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12605                }
12606            }
12607        }
12608
12609        if (mPersistentStartingProcesses.size() > 0) {
12610            if (needSep) pw.println();
12611            needSep = true;
12612            printedAnything = true;
12613            pw.println("  Persisent processes that are starting:");
12614            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12615                    "Starting Norm", "Restarting PERS", dumpPackage);
12616        }
12617
12618        if (mRemovedProcesses.size() > 0) {
12619            if (needSep) pw.println();
12620            needSep = true;
12621            printedAnything = true;
12622            pw.println("  Processes that are being removed:");
12623            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12624                    "Removed Norm", "Removed PERS", dumpPackage);
12625        }
12626
12627        if (mProcessesOnHold.size() > 0) {
12628            if (needSep) pw.println();
12629            needSep = true;
12630            printedAnything = true;
12631            pw.println("  Processes that are on old until the system is ready:");
12632            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12633                    "OnHold Norm", "OnHold PERS", dumpPackage);
12634        }
12635
12636        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12637
12638        if (mProcessCrashTimes.getMap().size() > 0) {
12639            boolean printed = false;
12640            long now = SystemClock.uptimeMillis();
12641            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12642            final int NP = pmap.size();
12643            for (int ip=0; ip<NP; ip++) {
12644                String pname = pmap.keyAt(ip);
12645                SparseArray<Long> uids = pmap.valueAt(ip);
12646                final int N = uids.size();
12647                for (int i=0; i<N; i++) {
12648                    int puid = uids.keyAt(i);
12649                    ProcessRecord r = mProcessNames.get(pname, puid);
12650                    if (dumpPackage != null && (r == null
12651                            || !r.pkgList.containsKey(dumpPackage))) {
12652                        continue;
12653                    }
12654                    if (!printed) {
12655                        if (needSep) pw.println();
12656                        needSep = true;
12657                        pw.println("  Time since processes crashed:");
12658                        printed = true;
12659                        printedAnything = true;
12660                    }
12661                    pw.print("    Process "); pw.print(pname);
12662                            pw.print(" uid "); pw.print(puid);
12663                            pw.print(": last crashed ");
12664                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12665                            pw.println(" ago");
12666                }
12667            }
12668        }
12669
12670        if (mBadProcesses.getMap().size() > 0) {
12671            boolean printed = false;
12672            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12673            final int NP = pmap.size();
12674            for (int ip=0; ip<NP; ip++) {
12675                String pname = pmap.keyAt(ip);
12676                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12677                final int N = uids.size();
12678                for (int i=0; i<N; i++) {
12679                    int puid = uids.keyAt(i);
12680                    ProcessRecord r = mProcessNames.get(pname, puid);
12681                    if (dumpPackage != null && (r == null
12682                            || !r.pkgList.containsKey(dumpPackage))) {
12683                        continue;
12684                    }
12685                    if (!printed) {
12686                        if (needSep) pw.println();
12687                        needSep = true;
12688                        pw.println("  Bad processes:");
12689                        printedAnything = true;
12690                    }
12691                    BadProcessInfo info = uids.valueAt(i);
12692                    pw.print("    Bad process "); pw.print(pname);
12693                            pw.print(" uid "); pw.print(puid);
12694                            pw.print(": crashed at time "); pw.println(info.time);
12695                    if (info.shortMsg != null) {
12696                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12697                    }
12698                    if (info.longMsg != null) {
12699                        pw.print("      Long msg: "); pw.println(info.longMsg);
12700                    }
12701                    if (info.stack != null) {
12702                        pw.println("      Stack:");
12703                        int lastPos = 0;
12704                        for (int pos=0; pos<info.stack.length(); pos++) {
12705                            if (info.stack.charAt(pos) == '\n') {
12706                                pw.print("        ");
12707                                pw.write(info.stack, lastPos, pos-lastPos);
12708                                pw.println();
12709                                lastPos = pos+1;
12710                            }
12711                        }
12712                        if (lastPos < info.stack.length()) {
12713                            pw.print("        ");
12714                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12715                            pw.println();
12716                        }
12717                    }
12718                }
12719            }
12720        }
12721
12722        if (dumpPackage == null) {
12723            pw.println();
12724            needSep = false;
12725            pw.println("  mStartedUsers:");
12726            for (int i=0; i<mStartedUsers.size(); i++) {
12727                UserStartedState uss = mStartedUsers.valueAt(i);
12728                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12729                        pw.print(": "); uss.dump("", pw);
12730            }
12731            pw.print("  mStartedUserArray: [");
12732            for (int i=0; i<mStartedUserArray.length; i++) {
12733                if (i > 0) pw.print(", ");
12734                pw.print(mStartedUserArray[i]);
12735            }
12736            pw.println("]");
12737            pw.print("  mUserLru: [");
12738            for (int i=0; i<mUserLru.size(); i++) {
12739                if (i > 0) pw.print(", ");
12740                pw.print(mUserLru.get(i));
12741            }
12742            pw.println("]");
12743            if (dumpAll) {
12744                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12745            }
12746            synchronized (mUserProfileGroupIdsSelfLocked) {
12747                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12748                    pw.println("  mUserProfileGroupIds:");
12749                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12750                        pw.print("    User #");
12751                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12752                        pw.print(" -> profile #");
12753                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12754                    }
12755                }
12756            }
12757        }
12758        if (mHomeProcess != null && (dumpPackage == null
12759                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12760            if (needSep) {
12761                pw.println();
12762                needSep = false;
12763            }
12764            pw.println("  mHomeProcess: " + mHomeProcess);
12765        }
12766        if (mPreviousProcess != null && (dumpPackage == null
12767                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12768            if (needSep) {
12769                pw.println();
12770                needSep = false;
12771            }
12772            pw.println("  mPreviousProcess: " + mPreviousProcess);
12773        }
12774        if (dumpAll) {
12775            StringBuilder sb = new StringBuilder(128);
12776            sb.append("  mPreviousProcessVisibleTime: ");
12777            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12778            pw.println(sb);
12779        }
12780        if (mHeavyWeightProcess != null && (dumpPackage == null
12781                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12782            if (needSep) {
12783                pw.println();
12784                needSep = false;
12785            }
12786            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12787        }
12788        if (dumpPackage == null) {
12789            pw.println("  mConfiguration: " + mConfiguration);
12790        }
12791        if (dumpAll) {
12792            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12793            if (mCompatModePackages.getPackages().size() > 0) {
12794                boolean printed = false;
12795                for (Map.Entry<String, Integer> entry
12796                        : mCompatModePackages.getPackages().entrySet()) {
12797                    String pkg = entry.getKey();
12798                    int mode = entry.getValue();
12799                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12800                        continue;
12801                    }
12802                    if (!printed) {
12803                        pw.println("  mScreenCompatPackages:");
12804                        printed = true;
12805                    }
12806                    pw.print("    "); pw.print(pkg); pw.print(": ");
12807                            pw.print(mode); pw.println();
12808                }
12809            }
12810        }
12811        if (dumpPackage == null) {
12812            pw.println("  mWakefulness="
12813                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12814            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12815                    + lockScreenShownToString());
12816            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
12817                    + " mTestPssMode=" + mTestPssMode);
12818        }
12819        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12820                || mOrigWaitForDebugger) {
12821            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12822                    || dumpPackage.equals(mOrigDebugApp)) {
12823                if (needSep) {
12824                    pw.println();
12825                    needSep = false;
12826                }
12827                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12828                        + " mDebugTransient=" + mDebugTransient
12829                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12830            }
12831        }
12832        if (mMemWatchProcesses.size() > 0) {
12833            pw.println("  Mem watch processes:");
12834            for (int i=0; i<mMemWatchProcesses.size(); i++) {
12835                if (needSep) {
12836                    pw.println();
12837                    needSep = false;
12838                }
12839                pw.print("    "); pw.print(mMemWatchProcesses.keyAt(i));
12840                pw.print(": "); DebugUtils.printSizeValue(pw, mMemWatchProcesses.valueAt(i));
12841                pw.println();
12842            }
12843            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
12844            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
12845            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
12846                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
12847        }
12848        if (mOpenGlTraceApp != null) {
12849            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12850                if (needSep) {
12851                    pw.println();
12852                    needSep = false;
12853                }
12854                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12855            }
12856        }
12857        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12858                || mProfileFd != null) {
12859            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12860                if (needSep) {
12861                    pw.println();
12862                    needSep = false;
12863                }
12864                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12865                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12866                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12867                        + mAutoStopProfiler);
12868                pw.println("  mProfileType=" + mProfileType);
12869            }
12870        }
12871        if (dumpPackage == null) {
12872            if (mAlwaysFinishActivities || mController != null) {
12873                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12874                        + " mController=" + mController);
12875            }
12876            if (dumpAll) {
12877                pw.println("  Total persistent processes: " + numPers);
12878                pw.println("  mProcessesReady=" + mProcessesReady
12879                        + " mSystemReady=" + mSystemReady
12880                        + " mBooted=" + mBooted
12881                        + " mFactoryTest=" + mFactoryTest);
12882                pw.println("  mBooting=" + mBooting
12883                        + " mCallFinishBooting=" + mCallFinishBooting
12884                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12885                pw.print("  mLastPowerCheckRealtime=");
12886                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12887                        pw.println("");
12888                pw.print("  mLastPowerCheckUptime=");
12889                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12890                        pw.println("");
12891                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12892                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12893                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12894                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12895                        + " (" + mLruProcesses.size() + " total)"
12896                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12897                        + " mNumServiceProcs=" + mNumServiceProcs
12898                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12899                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12900                        + " mLastMemoryLevel" + mLastMemoryLevel
12901                        + " mLastNumProcesses" + mLastNumProcesses);
12902                long now = SystemClock.uptimeMillis();
12903                pw.print("  mLastIdleTime=");
12904                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12905                        pw.print(" mLowRamSinceLastIdle=");
12906                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12907                        pw.println();
12908            }
12909        }
12910
12911        if (!printedAnything) {
12912            pw.println("  (nothing)");
12913        }
12914    }
12915
12916    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12917            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12918        if (mProcessesToGc.size() > 0) {
12919            boolean printed = false;
12920            long now = SystemClock.uptimeMillis();
12921            for (int i=0; i<mProcessesToGc.size(); i++) {
12922                ProcessRecord proc = mProcessesToGc.get(i);
12923                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12924                    continue;
12925                }
12926                if (!printed) {
12927                    if (needSep) pw.println();
12928                    needSep = true;
12929                    pw.println("  Processes that are waiting to GC:");
12930                    printed = true;
12931                }
12932                pw.print("    Process "); pw.println(proc);
12933                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12934                        pw.print(", last gced=");
12935                        pw.print(now-proc.lastRequestedGc);
12936                        pw.print(" ms ago, last lowMem=");
12937                        pw.print(now-proc.lastLowMemory);
12938                        pw.println(" ms ago");
12939
12940            }
12941        }
12942        return needSep;
12943    }
12944
12945    void printOomLevel(PrintWriter pw, String name, int adj) {
12946        pw.print("    ");
12947        if (adj >= 0) {
12948            pw.print(' ');
12949            if (adj < 10) pw.print(' ');
12950        } else {
12951            if (adj > -10) pw.print(' ');
12952        }
12953        pw.print(adj);
12954        pw.print(": ");
12955        pw.print(name);
12956        pw.print(" (");
12957        pw.print(mProcessList.getMemLevel(adj)/1024);
12958        pw.println(" kB)");
12959    }
12960
12961    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12962            int opti, boolean dumpAll) {
12963        boolean needSep = false;
12964
12965        if (mLruProcesses.size() > 0) {
12966            if (needSep) pw.println();
12967            needSep = true;
12968            pw.println("  OOM levels:");
12969            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12970            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12971            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12972            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12973            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12974            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12975            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12976            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12977            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12978            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12979            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12980            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12981            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12982            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12983
12984            if (needSep) pw.println();
12985            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12986                    pw.print(" total, non-act at ");
12987                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12988                    pw.print(", non-svc at ");
12989                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12990                    pw.println("):");
12991            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12992            needSep = true;
12993        }
12994
12995        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12996
12997        pw.println();
12998        pw.println("  mHomeProcess: " + mHomeProcess);
12999        pw.println("  mPreviousProcess: " + mPreviousProcess);
13000        if (mHeavyWeightProcess != null) {
13001            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13002        }
13003
13004        return true;
13005    }
13006
13007    /**
13008     * There are three ways to call this:
13009     *  - no provider specified: dump all the providers
13010     *  - a flattened component name that matched an existing provider was specified as the
13011     *    first arg: dump that one provider
13012     *  - the first arg isn't the flattened component name of an existing provider:
13013     *    dump all providers whose component contains the first arg as a substring
13014     */
13015    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13016            int opti, boolean dumpAll) {
13017        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13018    }
13019
13020    static class ItemMatcher {
13021        ArrayList<ComponentName> components;
13022        ArrayList<String> strings;
13023        ArrayList<Integer> objects;
13024        boolean all;
13025
13026        ItemMatcher() {
13027            all = true;
13028        }
13029
13030        void build(String name) {
13031            ComponentName componentName = ComponentName.unflattenFromString(name);
13032            if (componentName != null) {
13033                if (components == null) {
13034                    components = new ArrayList<ComponentName>();
13035                }
13036                components.add(componentName);
13037                all = false;
13038            } else {
13039                int objectId = 0;
13040                // Not a '/' separated full component name; maybe an object ID?
13041                try {
13042                    objectId = Integer.parseInt(name, 16);
13043                    if (objects == null) {
13044                        objects = new ArrayList<Integer>();
13045                    }
13046                    objects.add(objectId);
13047                    all = false;
13048                } catch (RuntimeException e) {
13049                    // Not an integer; just do string match.
13050                    if (strings == null) {
13051                        strings = new ArrayList<String>();
13052                    }
13053                    strings.add(name);
13054                    all = false;
13055                }
13056            }
13057        }
13058
13059        int build(String[] args, int opti) {
13060            for (; opti<args.length; opti++) {
13061                String name = args[opti];
13062                if ("--".equals(name)) {
13063                    return opti+1;
13064                }
13065                build(name);
13066            }
13067            return opti;
13068        }
13069
13070        boolean match(Object object, ComponentName comp) {
13071            if (all) {
13072                return true;
13073            }
13074            if (components != null) {
13075                for (int i=0; i<components.size(); i++) {
13076                    if (components.get(i).equals(comp)) {
13077                        return true;
13078                    }
13079                }
13080            }
13081            if (objects != null) {
13082                for (int i=0; i<objects.size(); i++) {
13083                    if (System.identityHashCode(object) == objects.get(i)) {
13084                        return true;
13085                    }
13086                }
13087            }
13088            if (strings != null) {
13089                String flat = comp.flattenToString();
13090                for (int i=0; i<strings.size(); i++) {
13091                    if (flat.contains(strings.get(i))) {
13092                        return true;
13093                    }
13094                }
13095            }
13096            return false;
13097        }
13098    }
13099
13100    /**
13101     * There are three things that cmd can be:
13102     *  - a flattened component name that matches an existing activity
13103     *  - the cmd arg isn't the flattened component name of an existing activity:
13104     *    dump all activity whose component contains the cmd as a substring
13105     *  - A hex number of the ActivityRecord object instance.
13106     */
13107    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13108            int opti, boolean dumpAll) {
13109        ArrayList<ActivityRecord> activities;
13110
13111        synchronized (this) {
13112            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13113        }
13114
13115        if (activities.size() <= 0) {
13116            return false;
13117        }
13118
13119        String[] newArgs = new String[args.length - opti];
13120        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13121
13122        TaskRecord lastTask = null;
13123        boolean needSep = false;
13124        for (int i=activities.size()-1; i>=0; i--) {
13125            ActivityRecord r = activities.get(i);
13126            if (needSep) {
13127                pw.println();
13128            }
13129            needSep = true;
13130            synchronized (this) {
13131                if (lastTask != r.task) {
13132                    lastTask = r.task;
13133                    pw.print("TASK "); pw.print(lastTask.affinity);
13134                            pw.print(" id="); pw.println(lastTask.taskId);
13135                    if (dumpAll) {
13136                        lastTask.dump(pw, "  ");
13137                    }
13138                }
13139            }
13140            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13141        }
13142        return true;
13143    }
13144
13145    /**
13146     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13147     * there is a thread associated with the activity.
13148     */
13149    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13150            final ActivityRecord r, String[] args, boolean dumpAll) {
13151        String innerPrefix = prefix + "  ";
13152        synchronized (this) {
13153            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13154                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13155                    pw.print(" pid=");
13156                    if (r.app != null) pw.println(r.app.pid);
13157                    else pw.println("(not running)");
13158            if (dumpAll) {
13159                r.dump(pw, innerPrefix);
13160            }
13161        }
13162        if (r.app != null && r.app.thread != null) {
13163            // flush anything that is already in the PrintWriter since the thread is going
13164            // to write to the file descriptor directly
13165            pw.flush();
13166            try {
13167                TransferPipe tp = new TransferPipe();
13168                try {
13169                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13170                            r.appToken, innerPrefix, args);
13171                    tp.go(fd);
13172                } finally {
13173                    tp.kill();
13174                }
13175            } catch (IOException e) {
13176                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13177            } catch (RemoteException e) {
13178                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13179            }
13180        }
13181    }
13182
13183    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13184            int opti, boolean dumpAll, String dumpPackage) {
13185        boolean needSep = false;
13186        boolean onlyHistory = false;
13187        boolean printedAnything = false;
13188
13189        if ("history".equals(dumpPackage)) {
13190            if (opti < args.length && "-s".equals(args[opti])) {
13191                dumpAll = false;
13192            }
13193            onlyHistory = true;
13194            dumpPackage = null;
13195        }
13196
13197        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13198        if (!onlyHistory && dumpAll) {
13199            if (mRegisteredReceivers.size() > 0) {
13200                boolean printed = false;
13201                Iterator it = mRegisteredReceivers.values().iterator();
13202                while (it.hasNext()) {
13203                    ReceiverList r = (ReceiverList)it.next();
13204                    if (dumpPackage != null && (r.app == null ||
13205                            !dumpPackage.equals(r.app.info.packageName))) {
13206                        continue;
13207                    }
13208                    if (!printed) {
13209                        pw.println("  Registered Receivers:");
13210                        needSep = true;
13211                        printed = true;
13212                        printedAnything = true;
13213                    }
13214                    pw.print("  * "); pw.println(r);
13215                    r.dump(pw, "    ");
13216                }
13217            }
13218
13219            if (mReceiverResolver.dump(pw, needSep ?
13220                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13221                    "    ", dumpPackage, false, false)) {
13222                needSep = true;
13223                printedAnything = true;
13224            }
13225        }
13226
13227        for (BroadcastQueue q : mBroadcastQueues) {
13228            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13229            printedAnything |= needSep;
13230        }
13231
13232        needSep = true;
13233
13234        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13235            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13236                if (needSep) {
13237                    pw.println();
13238                }
13239                needSep = true;
13240                printedAnything = true;
13241                pw.print("  Sticky broadcasts for user ");
13242                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13243                StringBuilder sb = new StringBuilder(128);
13244                for (Map.Entry<String, ArrayList<Intent>> ent
13245                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13246                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13247                    if (dumpAll) {
13248                        pw.println(":");
13249                        ArrayList<Intent> intents = ent.getValue();
13250                        final int N = intents.size();
13251                        for (int i=0; i<N; i++) {
13252                            sb.setLength(0);
13253                            sb.append("    Intent: ");
13254                            intents.get(i).toShortString(sb, false, true, false, false);
13255                            pw.println(sb.toString());
13256                            Bundle bundle = intents.get(i).getExtras();
13257                            if (bundle != null) {
13258                                pw.print("      ");
13259                                pw.println(bundle.toString());
13260                            }
13261                        }
13262                    } else {
13263                        pw.println("");
13264                    }
13265                }
13266            }
13267        }
13268
13269        if (!onlyHistory && dumpAll) {
13270            pw.println();
13271            for (BroadcastQueue queue : mBroadcastQueues) {
13272                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13273                        + queue.mBroadcastsScheduled);
13274            }
13275            pw.println("  mHandler:");
13276            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13277            needSep = true;
13278            printedAnything = true;
13279        }
13280
13281        if (!printedAnything) {
13282            pw.println("  (nothing)");
13283        }
13284    }
13285
13286    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13287            int opti, boolean dumpAll, String dumpPackage) {
13288        boolean needSep;
13289        boolean printedAnything = false;
13290
13291        ItemMatcher matcher = new ItemMatcher();
13292        matcher.build(args, opti);
13293
13294        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13295
13296        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13297        printedAnything |= needSep;
13298
13299        if (mLaunchingProviders.size() > 0) {
13300            boolean printed = false;
13301            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13302                ContentProviderRecord r = mLaunchingProviders.get(i);
13303                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13304                    continue;
13305                }
13306                if (!printed) {
13307                    if (needSep) pw.println();
13308                    needSep = true;
13309                    pw.println("  Launching content providers:");
13310                    printed = true;
13311                    printedAnything = true;
13312                }
13313                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13314                        pw.println(r);
13315            }
13316        }
13317
13318        if (mGrantedUriPermissions.size() > 0) {
13319            boolean printed = false;
13320            int dumpUid = -2;
13321            if (dumpPackage != null) {
13322                try {
13323                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13324                } catch (NameNotFoundException e) {
13325                    dumpUid = -1;
13326                }
13327            }
13328            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13329                int uid = mGrantedUriPermissions.keyAt(i);
13330                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13331                    continue;
13332                }
13333                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13334                if (!printed) {
13335                    if (needSep) pw.println();
13336                    needSep = true;
13337                    pw.println("  Granted Uri Permissions:");
13338                    printed = true;
13339                    printedAnything = true;
13340                }
13341                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13342                for (UriPermission perm : perms.values()) {
13343                    pw.print("    "); pw.println(perm);
13344                    if (dumpAll) {
13345                        perm.dump(pw, "      ");
13346                    }
13347                }
13348            }
13349        }
13350
13351        if (!printedAnything) {
13352            pw.println("  (nothing)");
13353        }
13354    }
13355
13356    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13357            int opti, boolean dumpAll, String dumpPackage) {
13358        boolean printed = false;
13359
13360        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13361
13362        if (mIntentSenderRecords.size() > 0) {
13363            Iterator<WeakReference<PendingIntentRecord>> it
13364                    = mIntentSenderRecords.values().iterator();
13365            while (it.hasNext()) {
13366                WeakReference<PendingIntentRecord> ref = it.next();
13367                PendingIntentRecord rec = ref != null ? ref.get(): null;
13368                if (dumpPackage != null && (rec == null
13369                        || !dumpPackage.equals(rec.key.packageName))) {
13370                    continue;
13371                }
13372                printed = true;
13373                if (rec != null) {
13374                    pw.print("  * "); pw.println(rec);
13375                    if (dumpAll) {
13376                        rec.dump(pw, "    ");
13377                    }
13378                } else {
13379                    pw.print("  * "); pw.println(ref);
13380                }
13381            }
13382        }
13383
13384        if (!printed) {
13385            pw.println("  (nothing)");
13386        }
13387    }
13388
13389    private static final int dumpProcessList(PrintWriter pw,
13390            ActivityManagerService service, List list,
13391            String prefix, String normalLabel, String persistentLabel,
13392            String dumpPackage) {
13393        int numPers = 0;
13394        final int N = list.size()-1;
13395        for (int i=N; i>=0; i--) {
13396            ProcessRecord r = (ProcessRecord)list.get(i);
13397            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13398                continue;
13399            }
13400            pw.println(String.format("%s%s #%2d: %s",
13401                    prefix, (r.persistent ? persistentLabel : normalLabel),
13402                    i, r.toString()));
13403            if (r.persistent) {
13404                numPers++;
13405            }
13406        }
13407        return numPers;
13408    }
13409
13410    private static final boolean dumpProcessOomList(PrintWriter pw,
13411            ActivityManagerService service, List<ProcessRecord> origList,
13412            String prefix, String normalLabel, String persistentLabel,
13413            boolean inclDetails, String dumpPackage) {
13414
13415        ArrayList<Pair<ProcessRecord, Integer>> list
13416                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13417        for (int i=0; i<origList.size(); i++) {
13418            ProcessRecord r = origList.get(i);
13419            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13420                continue;
13421            }
13422            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13423        }
13424
13425        if (list.size() <= 0) {
13426            return false;
13427        }
13428
13429        Comparator<Pair<ProcessRecord, Integer>> comparator
13430                = new Comparator<Pair<ProcessRecord, Integer>>() {
13431            @Override
13432            public int compare(Pair<ProcessRecord, Integer> object1,
13433                    Pair<ProcessRecord, Integer> object2) {
13434                if (object1.first.setAdj != object2.first.setAdj) {
13435                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13436                }
13437                if (object1.second.intValue() != object2.second.intValue()) {
13438                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13439                }
13440                return 0;
13441            }
13442        };
13443
13444        Collections.sort(list, comparator);
13445
13446        final long curRealtime = SystemClock.elapsedRealtime();
13447        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13448        final long curUptime = SystemClock.uptimeMillis();
13449        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13450
13451        for (int i=list.size()-1; i>=0; i--) {
13452            ProcessRecord r = list.get(i).first;
13453            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13454            char schedGroup;
13455            switch (r.setSchedGroup) {
13456                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13457                    schedGroup = 'B';
13458                    break;
13459                case Process.THREAD_GROUP_DEFAULT:
13460                    schedGroup = 'F';
13461                    break;
13462                default:
13463                    schedGroup = '?';
13464                    break;
13465            }
13466            char foreground;
13467            if (r.foregroundActivities) {
13468                foreground = 'A';
13469            } else if (r.foregroundServices) {
13470                foreground = 'S';
13471            } else {
13472                foreground = ' ';
13473            }
13474            String procState = ProcessList.makeProcStateString(r.curProcState);
13475            pw.print(prefix);
13476            pw.print(r.persistent ? persistentLabel : normalLabel);
13477            pw.print(" #");
13478            int num = (origList.size()-1)-list.get(i).second;
13479            if (num < 10) pw.print(' ');
13480            pw.print(num);
13481            pw.print(": ");
13482            pw.print(oomAdj);
13483            pw.print(' ');
13484            pw.print(schedGroup);
13485            pw.print('/');
13486            pw.print(foreground);
13487            pw.print('/');
13488            pw.print(procState);
13489            pw.print(" trm:");
13490            if (r.trimMemoryLevel < 10) pw.print(' ');
13491            pw.print(r.trimMemoryLevel);
13492            pw.print(' ');
13493            pw.print(r.toShortString());
13494            pw.print(" (");
13495            pw.print(r.adjType);
13496            pw.println(')');
13497            if (r.adjSource != null || r.adjTarget != null) {
13498                pw.print(prefix);
13499                pw.print("    ");
13500                if (r.adjTarget instanceof ComponentName) {
13501                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13502                } else if (r.adjTarget != null) {
13503                    pw.print(r.adjTarget.toString());
13504                } else {
13505                    pw.print("{null}");
13506                }
13507                pw.print("<=");
13508                if (r.adjSource instanceof ProcessRecord) {
13509                    pw.print("Proc{");
13510                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13511                    pw.println("}");
13512                } else if (r.adjSource != null) {
13513                    pw.println(r.adjSource.toString());
13514                } else {
13515                    pw.println("{null}");
13516                }
13517            }
13518            if (inclDetails) {
13519                pw.print(prefix);
13520                pw.print("    ");
13521                pw.print("oom: max="); pw.print(r.maxAdj);
13522                pw.print(" curRaw="); pw.print(r.curRawAdj);
13523                pw.print(" setRaw="); pw.print(r.setRawAdj);
13524                pw.print(" cur="); pw.print(r.curAdj);
13525                pw.print(" set="); pw.println(r.setAdj);
13526                pw.print(prefix);
13527                pw.print("    ");
13528                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13529                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13530                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
13531                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
13532                pw.println();
13533                pw.print(prefix);
13534                pw.print("    ");
13535                pw.print("cached="); pw.print(r.cached);
13536                pw.print(" empty="); pw.print(r.empty);
13537                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13538
13539                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13540                    if (r.lastWakeTime != 0) {
13541                        long wtime;
13542                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13543                        synchronized (stats) {
13544                            wtime = stats.getProcessWakeTime(r.info.uid,
13545                                    r.pid, curRealtime);
13546                        }
13547                        long timeUsed = wtime - r.lastWakeTime;
13548                        pw.print(prefix);
13549                        pw.print("    ");
13550                        pw.print("keep awake over ");
13551                        TimeUtils.formatDuration(realtimeSince, pw);
13552                        pw.print(" used ");
13553                        TimeUtils.formatDuration(timeUsed, pw);
13554                        pw.print(" (");
13555                        pw.print((timeUsed*100)/realtimeSince);
13556                        pw.println("%)");
13557                    }
13558                    if (r.lastCpuTime != 0) {
13559                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13560                        pw.print(prefix);
13561                        pw.print("    ");
13562                        pw.print("run cpu over ");
13563                        TimeUtils.formatDuration(uptimeSince, pw);
13564                        pw.print(" used ");
13565                        TimeUtils.formatDuration(timeUsed, pw);
13566                        pw.print(" (");
13567                        pw.print((timeUsed*100)/uptimeSince);
13568                        pw.println("%)");
13569                    }
13570                }
13571            }
13572        }
13573        return true;
13574    }
13575
13576    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13577            String[] args) {
13578        ArrayList<ProcessRecord> procs;
13579        synchronized (this) {
13580            if (args != null && args.length > start
13581                    && args[start].charAt(0) != '-') {
13582                procs = new ArrayList<ProcessRecord>();
13583                int pid = -1;
13584                try {
13585                    pid = Integer.parseInt(args[start]);
13586                } catch (NumberFormatException e) {
13587                }
13588                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13589                    ProcessRecord proc = mLruProcesses.get(i);
13590                    if (proc.pid == pid) {
13591                        procs.add(proc);
13592                    } else if (allPkgs && proc.pkgList != null
13593                            && proc.pkgList.containsKey(args[start])) {
13594                        procs.add(proc);
13595                    } else if (proc.processName.equals(args[start])) {
13596                        procs.add(proc);
13597                    }
13598                }
13599                if (procs.size() <= 0) {
13600                    return null;
13601                }
13602            } else {
13603                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13604            }
13605        }
13606        return procs;
13607    }
13608
13609    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13610            PrintWriter pw, String[] args) {
13611        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13612        if (procs == null) {
13613            pw.println("No process found for: " + args[0]);
13614            return;
13615        }
13616
13617        long uptime = SystemClock.uptimeMillis();
13618        long realtime = SystemClock.elapsedRealtime();
13619        pw.println("Applications Graphics Acceleration Info:");
13620        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13621
13622        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13623            ProcessRecord r = procs.get(i);
13624            if (r.thread != null) {
13625                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13626                pw.flush();
13627                try {
13628                    TransferPipe tp = new TransferPipe();
13629                    try {
13630                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13631                        tp.go(fd);
13632                    } finally {
13633                        tp.kill();
13634                    }
13635                } catch (IOException e) {
13636                    pw.println("Failure while dumping the app: " + r);
13637                    pw.flush();
13638                } catch (RemoteException e) {
13639                    pw.println("Got a RemoteException while dumping the app " + r);
13640                    pw.flush();
13641                }
13642            }
13643        }
13644    }
13645
13646    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13647        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13648        if (procs == null) {
13649            pw.println("No process found for: " + args[0]);
13650            return;
13651        }
13652
13653        pw.println("Applications Database Info:");
13654
13655        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13656            ProcessRecord r = procs.get(i);
13657            if (r.thread != null) {
13658                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13659                pw.flush();
13660                try {
13661                    TransferPipe tp = new TransferPipe();
13662                    try {
13663                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13664                        tp.go(fd);
13665                    } finally {
13666                        tp.kill();
13667                    }
13668                } catch (IOException e) {
13669                    pw.println("Failure while dumping the app: " + r);
13670                    pw.flush();
13671                } catch (RemoteException e) {
13672                    pw.println("Got a RemoteException while dumping the app " + r);
13673                    pw.flush();
13674                }
13675            }
13676        }
13677    }
13678
13679    final static class MemItem {
13680        final boolean isProc;
13681        final String label;
13682        final String shortLabel;
13683        final long pss;
13684        final int id;
13685        final boolean hasActivities;
13686        ArrayList<MemItem> subitems;
13687
13688        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13689                boolean _hasActivities) {
13690            isProc = true;
13691            label = _label;
13692            shortLabel = _shortLabel;
13693            pss = _pss;
13694            id = _id;
13695            hasActivities = _hasActivities;
13696        }
13697
13698        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13699            isProc = false;
13700            label = _label;
13701            shortLabel = _shortLabel;
13702            pss = _pss;
13703            id = _id;
13704            hasActivities = false;
13705        }
13706    }
13707
13708    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13709            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13710        if (sort && !isCompact) {
13711            Collections.sort(items, new Comparator<MemItem>() {
13712                @Override
13713                public int compare(MemItem lhs, MemItem rhs) {
13714                    if (lhs.pss < rhs.pss) {
13715                        return 1;
13716                    } else if (lhs.pss > rhs.pss) {
13717                        return -1;
13718                    }
13719                    return 0;
13720                }
13721            });
13722        }
13723
13724        for (int i=0; i<items.size(); i++) {
13725            MemItem mi = items.get(i);
13726            if (!isCompact) {
13727                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13728            } else if (mi.isProc) {
13729                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13730                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13731                pw.println(mi.hasActivities ? ",a" : ",e");
13732            } else {
13733                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13734                pw.println(mi.pss);
13735            }
13736            if (mi.subitems != null) {
13737                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13738                        true, isCompact);
13739            }
13740        }
13741    }
13742
13743    // These are in KB.
13744    static final long[] DUMP_MEM_BUCKETS = new long[] {
13745        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13746        120*1024, 160*1024, 200*1024,
13747        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13748        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13749    };
13750
13751    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13752            boolean stackLike) {
13753        int start = label.lastIndexOf('.');
13754        if (start >= 0) start++;
13755        else start = 0;
13756        int end = label.length();
13757        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13758            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13759                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13760                out.append(bucket);
13761                out.append(stackLike ? "MB." : "MB ");
13762                out.append(label, start, end);
13763                return;
13764            }
13765        }
13766        out.append(memKB/1024);
13767        out.append(stackLike ? "MB." : "MB ");
13768        out.append(label, start, end);
13769    }
13770
13771    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13772            ProcessList.NATIVE_ADJ,
13773            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13774            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13775            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13776            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13777            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13778            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13779    };
13780    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13781            "Native",
13782            "System", "Persistent", "Persistent Service", "Foreground",
13783            "Visible", "Perceptible",
13784            "Heavy Weight", "Backup",
13785            "A Services", "Home",
13786            "Previous", "B Services", "Cached"
13787    };
13788    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13789            "native",
13790            "sys", "pers", "persvc", "fore",
13791            "vis", "percept",
13792            "heavy", "backup",
13793            "servicea", "home",
13794            "prev", "serviceb", "cached"
13795    };
13796
13797    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13798            long realtime, boolean isCheckinRequest, boolean isCompact) {
13799        if (isCheckinRequest || isCompact) {
13800            // short checkin version
13801            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13802        } else {
13803            pw.println("Applications Memory Usage (kB):");
13804            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13805        }
13806    }
13807
13808    private static final int KSM_SHARED = 0;
13809    private static final int KSM_SHARING = 1;
13810    private static final int KSM_UNSHARED = 2;
13811    private static final int KSM_VOLATILE = 3;
13812
13813    private final long[] getKsmInfo() {
13814        long[] longOut = new long[4];
13815        final int[] SINGLE_LONG_FORMAT = new int[] {
13816            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13817        };
13818        long[] longTmp = new long[1];
13819        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13820                SINGLE_LONG_FORMAT, null, longTmp, null);
13821        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13822        longTmp[0] = 0;
13823        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13824                SINGLE_LONG_FORMAT, null, longTmp, null);
13825        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13826        longTmp[0] = 0;
13827        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13828                SINGLE_LONG_FORMAT, null, longTmp, null);
13829        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13830        longTmp[0] = 0;
13831        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13832                SINGLE_LONG_FORMAT, null, longTmp, null);
13833        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13834        return longOut;
13835    }
13836
13837    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13838            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13839        boolean dumpDetails = false;
13840        boolean dumpFullDetails = false;
13841        boolean dumpDalvik = false;
13842        boolean oomOnly = false;
13843        boolean isCompact = false;
13844        boolean localOnly = false;
13845        boolean packages = false;
13846
13847        int opti = 0;
13848        while (opti < args.length) {
13849            String opt = args[opti];
13850            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13851                break;
13852            }
13853            opti++;
13854            if ("-a".equals(opt)) {
13855                dumpDetails = true;
13856                dumpFullDetails = true;
13857                dumpDalvik = true;
13858            } else if ("-d".equals(opt)) {
13859                dumpDalvik = true;
13860            } else if ("-c".equals(opt)) {
13861                isCompact = true;
13862            } else if ("--oom".equals(opt)) {
13863                oomOnly = true;
13864            } else if ("--local".equals(opt)) {
13865                localOnly = true;
13866            } else if ("--package".equals(opt)) {
13867                packages = true;
13868            } else if ("-h".equals(opt)) {
13869                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13870                pw.println("  -a: include all available information for each process.");
13871                pw.println("  -d: include dalvik details when dumping process details.");
13872                pw.println("  -c: dump in a compact machine-parseable representation.");
13873                pw.println("  --oom: only show processes organized by oom adj.");
13874                pw.println("  --local: only collect details locally, don't call process.");
13875                pw.println("  --package: interpret process arg as package, dumping all");
13876                pw.println("             processes that have loaded that package.");
13877                pw.println("If [process] is specified it can be the name or ");
13878                pw.println("pid of a specific process to dump.");
13879                return;
13880            } else {
13881                pw.println("Unknown argument: " + opt + "; use -h for help");
13882            }
13883        }
13884
13885        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13886        long uptime = SystemClock.uptimeMillis();
13887        long realtime = SystemClock.elapsedRealtime();
13888        final long[] tmpLong = new long[1];
13889
13890        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13891        if (procs == null) {
13892            // No Java processes.  Maybe they want to print a native process.
13893            if (args != null && args.length > opti
13894                    && args[opti].charAt(0) != '-') {
13895                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13896                        = new ArrayList<ProcessCpuTracker.Stats>();
13897                updateCpuStatsNow();
13898                int findPid = -1;
13899                try {
13900                    findPid = Integer.parseInt(args[opti]);
13901                } catch (NumberFormatException e) {
13902                }
13903                synchronized (mProcessCpuTracker) {
13904                    final int N = mProcessCpuTracker.countStats();
13905                    for (int i=0; i<N; i++) {
13906                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13907                        if (st.pid == findPid || (st.baseName != null
13908                                && st.baseName.equals(args[opti]))) {
13909                            nativeProcs.add(st);
13910                        }
13911                    }
13912                }
13913                if (nativeProcs.size() > 0) {
13914                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13915                            isCompact);
13916                    Debug.MemoryInfo mi = null;
13917                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13918                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13919                        final int pid = r.pid;
13920                        if (!isCheckinRequest && dumpDetails) {
13921                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13922                        }
13923                        if (mi == null) {
13924                            mi = new Debug.MemoryInfo();
13925                        }
13926                        if (dumpDetails || (!brief && !oomOnly)) {
13927                            Debug.getMemoryInfo(pid, mi);
13928                        } else {
13929                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
13930                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13931                        }
13932                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13933                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13934                        if (isCheckinRequest) {
13935                            pw.println();
13936                        }
13937                    }
13938                    return;
13939                }
13940            }
13941            pw.println("No process found for: " + args[opti]);
13942            return;
13943        }
13944
13945        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13946            dumpDetails = true;
13947        }
13948
13949        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13950
13951        String[] innerArgs = new String[args.length-opti];
13952        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13953
13954        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13955        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13956        long nativePss = 0;
13957        long dalvikPss = 0;
13958        long otherPss = 0;
13959        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13960
13961        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13962        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13963                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13964
13965        long totalPss = 0;
13966        long cachedPss = 0;
13967
13968        Debug.MemoryInfo mi = null;
13969        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13970            final ProcessRecord r = procs.get(i);
13971            final IApplicationThread thread;
13972            final int pid;
13973            final int oomAdj;
13974            final boolean hasActivities;
13975            synchronized (this) {
13976                thread = r.thread;
13977                pid = r.pid;
13978                oomAdj = r.getSetAdjWithServices();
13979                hasActivities = r.activities.size() > 0;
13980            }
13981            if (thread != null) {
13982                if (!isCheckinRequest && dumpDetails) {
13983                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13984                }
13985                if (mi == null) {
13986                    mi = new Debug.MemoryInfo();
13987                }
13988                if (dumpDetails || (!brief && !oomOnly)) {
13989                    Debug.getMemoryInfo(pid, mi);
13990                } else {
13991                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
13992                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13993                }
13994                if (dumpDetails) {
13995                    if (localOnly) {
13996                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13997                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13998                        if (isCheckinRequest) {
13999                            pw.println();
14000                        }
14001                    } else {
14002                        try {
14003                            pw.flush();
14004                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14005                                    dumpDalvik, innerArgs);
14006                        } catch (RemoteException e) {
14007                            if (!isCheckinRequest) {
14008                                pw.println("Got RemoteException!");
14009                                pw.flush();
14010                            }
14011                        }
14012                    }
14013                }
14014
14015                final long myTotalPss = mi.getTotalPss();
14016                final long myTotalUss = mi.getTotalUss();
14017
14018                synchronized (this) {
14019                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14020                        // Record this for posterity if the process has been stable.
14021                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14022                    }
14023                }
14024
14025                if (!isCheckinRequest && mi != null) {
14026                    totalPss += myTotalPss;
14027                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14028                            (hasActivities ? " / activities)" : ")"),
14029                            r.processName, myTotalPss, pid, hasActivities);
14030                    procMems.add(pssItem);
14031                    procMemsMap.put(pid, pssItem);
14032
14033                    nativePss += mi.nativePss;
14034                    dalvikPss += mi.dalvikPss;
14035                    otherPss += mi.otherPss;
14036                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14037                        long mem = mi.getOtherPss(j);
14038                        miscPss[j] += mem;
14039                        otherPss -= mem;
14040                    }
14041
14042                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14043                        cachedPss += myTotalPss;
14044                    }
14045
14046                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14047                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14048                                || oomIndex == (oomPss.length-1)) {
14049                            oomPss[oomIndex] += myTotalPss;
14050                            if (oomProcs[oomIndex] == null) {
14051                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14052                            }
14053                            oomProcs[oomIndex].add(pssItem);
14054                            break;
14055                        }
14056                    }
14057                }
14058            }
14059        }
14060
14061        long nativeProcTotalPss = 0;
14062
14063        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14064            // If we are showing aggregations, also look for native processes to
14065            // include so that our aggregations are more accurate.
14066            updateCpuStatsNow();
14067            mi = null;
14068            synchronized (mProcessCpuTracker) {
14069                final int N = mProcessCpuTracker.countStats();
14070                for (int i=0; i<N; i++) {
14071                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14072                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14073                        if (mi == null) {
14074                            mi = new Debug.MemoryInfo();
14075                        }
14076                        if (!brief && !oomOnly) {
14077                            Debug.getMemoryInfo(st.pid, mi);
14078                        } else {
14079                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14080                            mi.nativePrivateDirty = (int)tmpLong[0];
14081                        }
14082
14083                        final long myTotalPss = mi.getTotalPss();
14084                        totalPss += myTotalPss;
14085                        nativeProcTotalPss += myTotalPss;
14086
14087                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14088                                st.name, myTotalPss, st.pid, false);
14089                        procMems.add(pssItem);
14090
14091                        nativePss += mi.nativePss;
14092                        dalvikPss += mi.dalvikPss;
14093                        otherPss += mi.otherPss;
14094                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14095                            long mem = mi.getOtherPss(j);
14096                            miscPss[j] += mem;
14097                            otherPss -= mem;
14098                        }
14099                        oomPss[0] += myTotalPss;
14100                        if (oomProcs[0] == null) {
14101                            oomProcs[0] = new ArrayList<MemItem>();
14102                        }
14103                        oomProcs[0].add(pssItem);
14104                    }
14105                }
14106            }
14107
14108            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14109
14110            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14111            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14112            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14113            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14114                String label = Debug.MemoryInfo.getOtherLabel(j);
14115                catMems.add(new MemItem(label, label, miscPss[j], j));
14116            }
14117
14118            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14119            for (int j=0; j<oomPss.length; j++) {
14120                if (oomPss[j] != 0) {
14121                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14122                            : DUMP_MEM_OOM_LABEL[j];
14123                    MemItem item = new MemItem(label, label, oomPss[j],
14124                            DUMP_MEM_OOM_ADJ[j]);
14125                    item.subitems = oomProcs[j];
14126                    oomMems.add(item);
14127                }
14128            }
14129
14130            if (!brief && !oomOnly && !isCompact) {
14131                pw.println();
14132                pw.println("Total PSS by process:");
14133                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14134                pw.println();
14135            }
14136            if (!isCompact) {
14137                pw.println("Total PSS by OOM adjustment:");
14138            }
14139            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14140            if (!brief && !oomOnly) {
14141                PrintWriter out = categoryPw != null ? categoryPw : pw;
14142                if (!isCompact) {
14143                    out.println();
14144                    out.println("Total PSS by category:");
14145                }
14146                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14147            }
14148            if (!isCompact) {
14149                pw.println();
14150            }
14151            MemInfoReader memInfo = new MemInfoReader();
14152            memInfo.readMemInfo();
14153            if (nativeProcTotalPss > 0) {
14154                synchronized (this) {
14155                    final long cachedKb = memInfo.getCachedSizeKb();
14156                    final long freeKb = memInfo.getFreeSizeKb();
14157                    final long zramKb = memInfo.getZramTotalSizeKb();
14158                    final long kernelKb = memInfo.getKernelUsedSizeKb();
14159                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14160                            kernelKb*1024, nativeProcTotalPss*1024);
14161                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14162                            nativeProcTotalPss);
14163                }
14164            }
14165            if (!brief) {
14166                if (!isCompact) {
14167                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14168                    pw.print(" kB (status ");
14169                    switch (mLastMemoryLevel) {
14170                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14171                            pw.println("normal)");
14172                            break;
14173                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14174                            pw.println("moderate)");
14175                            break;
14176                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14177                            pw.println("low)");
14178                            break;
14179                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14180                            pw.println("critical)");
14181                            break;
14182                        default:
14183                            pw.print(mLastMemoryLevel);
14184                            pw.println(")");
14185                            break;
14186                    }
14187                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14188                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14189                            pw.print(cachedPss); pw.print(" cached pss + ");
14190                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14191                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14192                } else {
14193                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14194                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14195                            + memInfo.getFreeSizeKb()); pw.print(",");
14196                    pw.println(totalPss - cachedPss);
14197                }
14198            }
14199            if (!isCompact) {
14200                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14201                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14202                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14203                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14204                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14205                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14206                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14207            }
14208            if (!brief) {
14209                if (memInfo.getZramTotalSizeKb() != 0) {
14210                    if (!isCompact) {
14211                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14212                                pw.print(" kB physical used for ");
14213                                pw.print(memInfo.getSwapTotalSizeKb()
14214                                        - memInfo.getSwapFreeSizeKb());
14215                                pw.print(" kB in swap (");
14216                                pw.print(memInfo.getSwapTotalSizeKb());
14217                                pw.println(" kB total swap)");
14218                    } else {
14219                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14220                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14221                                pw.println(memInfo.getSwapFreeSizeKb());
14222                    }
14223                }
14224                final long[] ksm = getKsmInfo();
14225                if (!isCompact) {
14226                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14227                            || ksm[KSM_VOLATILE] != 0) {
14228                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14229                                pw.print(" kB saved from shared ");
14230                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14231                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14232                                pw.print(" kB unshared; ");
14233                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14234                    }
14235                    pw.print("   Tuning: ");
14236                    pw.print(ActivityManager.staticGetMemoryClass());
14237                    pw.print(" (large ");
14238                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14239                    pw.print("), oom ");
14240                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14241                    pw.print(" kB");
14242                    pw.print(", restore limit ");
14243                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14244                    pw.print(" kB");
14245                    if (ActivityManager.isLowRamDeviceStatic()) {
14246                        pw.print(" (low-ram)");
14247                    }
14248                    if (ActivityManager.isHighEndGfx()) {
14249                        pw.print(" (high-end-gfx)");
14250                    }
14251                    pw.println();
14252                } else {
14253                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14254                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14255                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14256                    pw.print("tuning,");
14257                    pw.print(ActivityManager.staticGetMemoryClass());
14258                    pw.print(',');
14259                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14260                    pw.print(',');
14261                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14262                    if (ActivityManager.isLowRamDeviceStatic()) {
14263                        pw.print(",low-ram");
14264                    }
14265                    if (ActivityManager.isHighEndGfx()) {
14266                        pw.print(",high-end-gfx");
14267                    }
14268                    pw.println();
14269                }
14270            }
14271        }
14272    }
14273
14274    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14275            long memtrack, String name) {
14276        sb.append("  ");
14277        sb.append(ProcessList.makeOomAdjString(oomAdj));
14278        sb.append(' ');
14279        sb.append(ProcessList.makeProcStateString(procState));
14280        sb.append(' ');
14281        ProcessList.appendRamKb(sb, pss);
14282        sb.append(" kB: ");
14283        sb.append(name);
14284        if (memtrack > 0) {
14285            sb.append(" (");
14286            sb.append(memtrack);
14287            sb.append(" kB memtrack)");
14288        }
14289    }
14290
14291    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14292        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14293        sb.append(" (pid ");
14294        sb.append(mi.pid);
14295        sb.append(") ");
14296        sb.append(mi.adjType);
14297        sb.append('\n');
14298        if (mi.adjReason != null) {
14299            sb.append("                      ");
14300            sb.append(mi.adjReason);
14301            sb.append('\n');
14302        }
14303    }
14304
14305    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14306        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14307        for (int i=0, N=memInfos.size(); i<N; i++) {
14308            ProcessMemInfo mi = memInfos.get(i);
14309            infoMap.put(mi.pid, mi);
14310        }
14311        updateCpuStatsNow();
14312        long[] memtrackTmp = new long[1];
14313        synchronized (mProcessCpuTracker) {
14314            final int N = mProcessCpuTracker.countStats();
14315            for (int i=0; i<N; i++) {
14316                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14317                if (st.vsize > 0) {
14318                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14319                    if (pss > 0) {
14320                        if (infoMap.indexOfKey(st.pid) < 0) {
14321                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14322                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14323                            mi.pss = pss;
14324                            mi.memtrack = memtrackTmp[0];
14325                            memInfos.add(mi);
14326                        }
14327                    }
14328                }
14329            }
14330        }
14331
14332        long totalPss = 0;
14333        long totalMemtrack = 0;
14334        for (int i=0, N=memInfos.size(); i<N; i++) {
14335            ProcessMemInfo mi = memInfos.get(i);
14336            if (mi.pss == 0) {
14337                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14338                mi.memtrack = memtrackTmp[0];
14339            }
14340            totalPss += mi.pss;
14341            totalMemtrack += mi.memtrack;
14342        }
14343        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14344            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14345                if (lhs.oomAdj != rhs.oomAdj) {
14346                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14347                }
14348                if (lhs.pss != rhs.pss) {
14349                    return lhs.pss < rhs.pss ? 1 : -1;
14350                }
14351                return 0;
14352            }
14353        });
14354
14355        StringBuilder tag = new StringBuilder(128);
14356        StringBuilder stack = new StringBuilder(128);
14357        tag.append("Low on memory -- ");
14358        appendMemBucket(tag, totalPss, "total", false);
14359        appendMemBucket(stack, totalPss, "total", true);
14360
14361        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14362        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14363        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14364
14365        boolean firstLine = true;
14366        int lastOomAdj = Integer.MIN_VALUE;
14367        long extraNativeRam = 0;
14368        long extraNativeMemtrack = 0;
14369        long cachedPss = 0;
14370        for (int i=0, N=memInfos.size(); i<N; i++) {
14371            ProcessMemInfo mi = memInfos.get(i);
14372
14373            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14374                cachedPss += mi.pss;
14375            }
14376
14377            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14378                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14379                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14380                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14381                if (lastOomAdj != mi.oomAdj) {
14382                    lastOomAdj = mi.oomAdj;
14383                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14384                        tag.append(" / ");
14385                    }
14386                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14387                        if (firstLine) {
14388                            stack.append(":");
14389                            firstLine = false;
14390                        }
14391                        stack.append("\n\t at ");
14392                    } else {
14393                        stack.append("$");
14394                    }
14395                } else {
14396                    tag.append(" ");
14397                    stack.append("$");
14398                }
14399                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14400                    appendMemBucket(tag, mi.pss, mi.name, false);
14401                }
14402                appendMemBucket(stack, mi.pss, mi.name, true);
14403                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14404                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14405                    stack.append("(");
14406                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14407                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14408                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14409                            stack.append(":");
14410                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14411                        }
14412                    }
14413                    stack.append(")");
14414                }
14415            }
14416
14417            appendMemInfo(fullNativeBuilder, mi);
14418            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14419                // The short form only has native processes that are >= 512K.
14420                if (mi.pss >= 512) {
14421                    appendMemInfo(shortNativeBuilder, mi);
14422                } else {
14423                    extraNativeRam += mi.pss;
14424                    extraNativeMemtrack += mi.memtrack;
14425                }
14426            } else {
14427                // Short form has all other details, but if we have collected RAM
14428                // from smaller native processes let's dump a summary of that.
14429                if (extraNativeRam > 0) {
14430                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14431                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14432                    shortNativeBuilder.append('\n');
14433                    extraNativeRam = 0;
14434                }
14435                appendMemInfo(fullJavaBuilder, mi);
14436            }
14437        }
14438
14439        fullJavaBuilder.append("           ");
14440        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14441        fullJavaBuilder.append(" kB: TOTAL");
14442        if (totalMemtrack > 0) {
14443            fullJavaBuilder.append(" (");
14444            fullJavaBuilder.append(totalMemtrack);
14445            fullJavaBuilder.append(" kB memtrack)");
14446        } else {
14447        }
14448        fullJavaBuilder.append("\n");
14449
14450        MemInfoReader memInfo = new MemInfoReader();
14451        memInfo.readMemInfo();
14452        final long[] infos = memInfo.getRawInfo();
14453
14454        StringBuilder memInfoBuilder = new StringBuilder(1024);
14455        Debug.getMemInfo(infos);
14456        memInfoBuilder.append("  MemInfo: ");
14457        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14458        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14459        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14460        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14461        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14462        memInfoBuilder.append("           ");
14463        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14464        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14465        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14466        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14467        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14468            memInfoBuilder.append("  ZRAM: ");
14469            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14470            memInfoBuilder.append(" kB RAM, ");
14471            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14472            memInfoBuilder.append(" kB swap total, ");
14473            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14474            memInfoBuilder.append(" kB swap free\n");
14475        }
14476        final long[] ksm = getKsmInfo();
14477        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14478                || ksm[KSM_VOLATILE] != 0) {
14479            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14480            memInfoBuilder.append(" kB saved from shared ");
14481            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14482            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14483            memInfoBuilder.append(" kB unshared; ");
14484            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14485        }
14486        memInfoBuilder.append("  Free RAM: ");
14487        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14488                + memInfo.getFreeSizeKb());
14489        memInfoBuilder.append(" kB\n");
14490        memInfoBuilder.append("  Used RAM: ");
14491        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14492        memInfoBuilder.append(" kB\n");
14493        memInfoBuilder.append("  Lost RAM: ");
14494        memInfoBuilder.append(memInfo.getTotalSizeKb()
14495                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14496                - memInfo.getKernelUsedSizeKb());
14497        memInfoBuilder.append(" kB\n");
14498        Slog.i(TAG, "Low on memory:");
14499        Slog.i(TAG, shortNativeBuilder.toString());
14500        Slog.i(TAG, fullJavaBuilder.toString());
14501        Slog.i(TAG, memInfoBuilder.toString());
14502
14503        StringBuilder dropBuilder = new StringBuilder(1024);
14504        /*
14505        StringWriter oomSw = new StringWriter();
14506        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14507        StringWriter catSw = new StringWriter();
14508        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14509        String[] emptyArgs = new String[] { };
14510        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14511        oomPw.flush();
14512        String oomString = oomSw.toString();
14513        */
14514        dropBuilder.append("Low on memory:");
14515        dropBuilder.append(stack);
14516        dropBuilder.append('\n');
14517        dropBuilder.append(fullNativeBuilder);
14518        dropBuilder.append(fullJavaBuilder);
14519        dropBuilder.append('\n');
14520        dropBuilder.append(memInfoBuilder);
14521        dropBuilder.append('\n');
14522        /*
14523        dropBuilder.append(oomString);
14524        dropBuilder.append('\n');
14525        */
14526        StringWriter catSw = new StringWriter();
14527        synchronized (ActivityManagerService.this) {
14528            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14529            String[] emptyArgs = new String[] { };
14530            catPw.println();
14531            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14532            catPw.println();
14533            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14534                    false, false, null);
14535            catPw.println();
14536            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14537            catPw.flush();
14538        }
14539        dropBuilder.append(catSw.toString());
14540        addErrorToDropBox("lowmem", null, "system_server", null,
14541                null, tag.toString(), dropBuilder.toString(), null, null);
14542        //Slog.i(TAG, "Sent to dropbox:");
14543        //Slog.i(TAG, dropBuilder.toString());
14544        synchronized (ActivityManagerService.this) {
14545            long now = SystemClock.uptimeMillis();
14546            if (mLastMemUsageReportTime < now) {
14547                mLastMemUsageReportTime = now;
14548            }
14549        }
14550    }
14551
14552    /**
14553     * Searches array of arguments for the specified string
14554     * @param args array of argument strings
14555     * @param value value to search for
14556     * @return true if the value is contained in the array
14557     */
14558    private static boolean scanArgs(String[] args, String value) {
14559        if (args != null) {
14560            for (String arg : args) {
14561                if (value.equals(arg)) {
14562                    return true;
14563                }
14564            }
14565        }
14566        return false;
14567    }
14568
14569    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14570            ContentProviderRecord cpr, boolean always) {
14571        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14572
14573        if (!inLaunching || always) {
14574            synchronized (cpr) {
14575                cpr.launchingApp = null;
14576                cpr.notifyAll();
14577            }
14578            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14579            String names[] = cpr.info.authority.split(";");
14580            for (int j = 0; j < names.length; j++) {
14581                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14582            }
14583        }
14584
14585        for (int i=0; i<cpr.connections.size(); i++) {
14586            ContentProviderConnection conn = cpr.connections.get(i);
14587            if (conn.waiting) {
14588                // If this connection is waiting for the provider, then we don't
14589                // need to mess with its process unless we are always removing
14590                // or for some reason the provider is not currently launching.
14591                if (inLaunching && !always) {
14592                    continue;
14593                }
14594            }
14595            ProcessRecord capp = conn.client;
14596            conn.dead = true;
14597            if (conn.stableCount > 0) {
14598                if (!capp.persistent && capp.thread != null
14599                        && capp.pid != 0
14600                        && capp.pid != MY_PID) {
14601                    capp.kill("depends on provider "
14602                            + cpr.name.flattenToShortString()
14603                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14604                }
14605            } else if (capp.thread != null && conn.provider.provider != null) {
14606                try {
14607                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14608                } catch (RemoteException e) {
14609                }
14610                // In the protocol here, we don't expect the client to correctly
14611                // clean up this connection, we'll just remove it.
14612                cpr.connections.remove(i);
14613                if (conn.client.conProviders.remove(conn)) {
14614                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14615                }
14616            }
14617        }
14618
14619        if (inLaunching && always) {
14620            mLaunchingProviders.remove(cpr);
14621        }
14622        return inLaunching;
14623    }
14624
14625    /**
14626     * Main code for cleaning up a process when it has gone away.  This is
14627     * called both as a result of the process dying, or directly when stopping
14628     * a process when running in single process mode.
14629     *
14630     * @return Returns true if the given process has been restarted, so the
14631     * app that was passed in must remain on the process lists.
14632     */
14633    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14634            boolean restarting, boolean allowRestart, int index) {
14635        if (index >= 0) {
14636            removeLruProcessLocked(app);
14637            ProcessList.remove(app.pid);
14638        }
14639
14640        mProcessesToGc.remove(app);
14641        mPendingPssProcesses.remove(app);
14642
14643        // Dismiss any open dialogs.
14644        if (app.crashDialog != null && !app.forceCrashReport) {
14645            app.crashDialog.dismiss();
14646            app.crashDialog = null;
14647        }
14648        if (app.anrDialog != null) {
14649            app.anrDialog.dismiss();
14650            app.anrDialog = null;
14651        }
14652        if (app.waitDialog != null) {
14653            app.waitDialog.dismiss();
14654            app.waitDialog = null;
14655        }
14656
14657        app.crashing = false;
14658        app.notResponding = false;
14659
14660        app.resetPackageList(mProcessStats);
14661        app.unlinkDeathRecipient();
14662        app.makeInactive(mProcessStats);
14663        app.waitingToKill = null;
14664        app.forcingToForeground = null;
14665        updateProcessForegroundLocked(app, false, false);
14666        app.foregroundActivities = false;
14667        app.hasShownUi = false;
14668        app.treatLikeActivity = false;
14669        app.hasAboveClient = false;
14670        app.hasClientActivities = false;
14671
14672        mServices.killServicesLocked(app, allowRestart);
14673
14674        boolean restart = false;
14675
14676        // Remove published content providers.
14677        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14678            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14679            final boolean always = app.bad || !allowRestart;
14680            if (removeDyingProviderLocked(app, cpr, always) || always) {
14681                // We left the provider in the launching list, need to
14682                // restart it.
14683                restart = true;
14684            }
14685
14686            cpr.provider = null;
14687            cpr.proc = null;
14688        }
14689        app.pubProviders.clear();
14690
14691        // Take care of any launching providers waiting for this process.
14692        if (checkAppInLaunchingProvidersLocked(app, false)) {
14693            restart = true;
14694        }
14695
14696        // Unregister from connected content providers.
14697        if (!app.conProviders.isEmpty()) {
14698            for (int i=0; i<app.conProviders.size(); i++) {
14699                ContentProviderConnection conn = app.conProviders.get(i);
14700                conn.provider.connections.remove(conn);
14701                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
14702                        conn.provider.name);
14703            }
14704            app.conProviders.clear();
14705        }
14706
14707        // At this point there may be remaining entries in mLaunchingProviders
14708        // where we were the only one waiting, so they are no longer of use.
14709        // Look for these and clean up if found.
14710        // XXX Commented out for now.  Trying to figure out a way to reproduce
14711        // the actual situation to identify what is actually going on.
14712        if (false) {
14713            for (int i=0; i<mLaunchingProviders.size(); i++) {
14714                ContentProviderRecord cpr = (ContentProviderRecord)
14715                        mLaunchingProviders.get(i);
14716                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14717                    synchronized (cpr) {
14718                        cpr.launchingApp = null;
14719                        cpr.notifyAll();
14720                    }
14721                }
14722            }
14723        }
14724
14725        skipCurrentReceiverLocked(app);
14726
14727        // Unregister any receivers.
14728        for (int i=app.receivers.size()-1; i>=0; i--) {
14729            removeReceiverLocked(app.receivers.valueAt(i));
14730        }
14731        app.receivers.clear();
14732
14733        // If the app is undergoing backup, tell the backup manager about it
14734        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14735            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
14736                    + mBackupTarget.appInfo + " died during backup");
14737            try {
14738                IBackupManager bm = IBackupManager.Stub.asInterface(
14739                        ServiceManager.getService(Context.BACKUP_SERVICE));
14740                bm.agentDisconnected(app.info.packageName);
14741            } catch (RemoteException e) {
14742                // can't happen; backup manager is local
14743            }
14744        }
14745
14746        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14747            ProcessChangeItem item = mPendingProcessChanges.get(i);
14748            if (item.pid == app.pid) {
14749                mPendingProcessChanges.remove(i);
14750                mAvailProcessChanges.add(item);
14751            }
14752        }
14753        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14754
14755        // If the caller is restarting this app, then leave it in its
14756        // current lists and let the caller take care of it.
14757        if (restarting) {
14758            return false;
14759        }
14760
14761        if (!app.persistent || app.isolated) {
14762            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
14763                    "Removing non-persistent process during cleanup: " + app);
14764            mProcessNames.remove(app.processName, app.uid);
14765            mIsolatedProcesses.remove(app.uid);
14766            if (mHeavyWeightProcess == app) {
14767                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14768                        mHeavyWeightProcess.userId, 0));
14769                mHeavyWeightProcess = null;
14770            }
14771        } else if (!app.removed) {
14772            // This app is persistent, so we need to keep its record around.
14773            // If it is not already on the pending app list, add it there
14774            // and start a new process for it.
14775            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14776                mPersistentStartingProcesses.add(app);
14777                restart = true;
14778            }
14779        }
14780        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
14781                TAG_CLEANUP, "Clean-up removing on hold: " + app);
14782        mProcessesOnHold.remove(app);
14783
14784        if (app == mHomeProcess) {
14785            mHomeProcess = null;
14786        }
14787        if (app == mPreviousProcess) {
14788            mPreviousProcess = null;
14789        }
14790
14791        if (restart && !app.isolated) {
14792            // We have components that still need to be running in the
14793            // process, so re-launch it.
14794            if (index < 0) {
14795                ProcessList.remove(app.pid);
14796            }
14797            mProcessNames.put(app.processName, app.uid, app);
14798            startProcessLocked(app, "restart", app.processName);
14799            return true;
14800        } else if (app.pid > 0 && app.pid != MY_PID) {
14801            // Goodbye!
14802            boolean removed;
14803            synchronized (mPidsSelfLocked) {
14804                mPidsSelfLocked.remove(app.pid);
14805                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14806            }
14807            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14808            if (app.isolated) {
14809                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14810            }
14811            app.setPid(0);
14812        }
14813        return false;
14814    }
14815
14816    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14817        // Look through the content providers we are waiting to have launched,
14818        // and if any run in this process then either schedule a restart of
14819        // the process or kill the client waiting for it if this process has
14820        // gone bad.
14821        int NL = mLaunchingProviders.size();
14822        boolean restart = false;
14823        for (int i=0; i<NL; i++) {
14824            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14825            if (cpr.launchingApp == app) {
14826                if (!alwaysBad && !app.bad) {
14827                    restart = true;
14828                } else {
14829                    removeDyingProviderLocked(app, cpr, true);
14830                    // cpr should have been removed from mLaunchingProviders
14831                    NL = mLaunchingProviders.size();
14832                    i--;
14833                }
14834            }
14835        }
14836        return restart;
14837    }
14838
14839    // =========================================================
14840    // SERVICES
14841    // =========================================================
14842
14843    @Override
14844    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14845            int flags) {
14846        enforceNotIsolatedCaller("getServices");
14847        synchronized (this) {
14848            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14849        }
14850    }
14851
14852    @Override
14853    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14854        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14855        synchronized (this) {
14856            return mServices.getRunningServiceControlPanelLocked(name);
14857        }
14858    }
14859
14860    @Override
14861    public ComponentName startService(IApplicationThread caller, Intent service,
14862            String resolvedType, int userId) {
14863        enforceNotIsolatedCaller("startService");
14864        // Refuse possible leaked file descriptors
14865        if (service != null && service.hasFileDescriptors() == true) {
14866            throw new IllegalArgumentException("File descriptors passed in Intent");
14867        }
14868
14869        if (DEBUG_SERVICE)
14870            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14871        synchronized(this) {
14872            final int callingPid = Binder.getCallingPid();
14873            final int callingUid = Binder.getCallingUid();
14874            final long origId = Binder.clearCallingIdentity();
14875            ComponentName res = mServices.startServiceLocked(caller, service,
14876                    resolvedType, callingPid, callingUid, userId);
14877            Binder.restoreCallingIdentity(origId);
14878            return res;
14879        }
14880    }
14881
14882    ComponentName startServiceInPackage(int uid,
14883            Intent service, String resolvedType, int userId) {
14884        synchronized(this) {
14885            if (DEBUG_SERVICE)
14886                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14887            final long origId = Binder.clearCallingIdentity();
14888            ComponentName res = mServices.startServiceLocked(null, service,
14889                    resolvedType, -1, uid, userId);
14890            Binder.restoreCallingIdentity(origId);
14891            return res;
14892        }
14893    }
14894
14895    @Override
14896    public int stopService(IApplicationThread caller, Intent service,
14897            String resolvedType, int userId) {
14898        enforceNotIsolatedCaller("stopService");
14899        // Refuse possible leaked file descriptors
14900        if (service != null && service.hasFileDescriptors() == true) {
14901            throw new IllegalArgumentException("File descriptors passed in Intent");
14902        }
14903
14904        synchronized(this) {
14905            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14906        }
14907    }
14908
14909    @Override
14910    public IBinder peekService(Intent service, String resolvedType) {
14911        enforceNotIsolatedCaller("peekService");
14912        // Refuse possible leaked file descriptors
14913        if (service != null && service.hasFileDescriptors() == true) {
14914            throw new IllegalArgumentException("File descriptors passed in Intent");
14915        }
14916        synchronized(this) {
14917            return mServices.peekServiceLocked(service, resolvedType);
14918        }
14919    }
14920
14921    @Override
14922    public boolean stopServiceToken(ComponentName className, IBinder token,
14923            int startId) {
14924        synchronized(this) {
14925            return mServices.stopServiceTokenLocked(className, token, startId);
14926        }
14927    }
14928
14929    @Override
14930    public void setServiceForeground(ComponentName className, IBinder token,
14931            int id, Notification notification, boolean removeNotification) {
14932        synchronized(this) {
14933            mServices.setServiceForegroundLocked(className, token, id, notification,
14934                    removeNotification);
14935        }
14936    }
14937
14938    @Override
14939    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14940            boolean requireFull, String name, String callerPackage) {
14941        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14942                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14943    }
14944
14945    int unsafeConvertIncomingUser(int userId) {
14946        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14947                ? mCurrentUserId : userId;
14948    }
14949
14950    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14951            int allowMode, String name, String callerPackage) {
14952        final int callingUserId = UserHandle.getUserId(callingUid);
14953        if (callingUserId == userId) {
14954            return userId;
14955        }
14956
14957        // Note that we may be accessing mCurrentUserId outside of a lock...
14958        // shouldn't be a big deal, if this is being called outside
14959        // of a locked context there is intrinsically a race with
14960        // the value the caller will receive and someone else changing it.
14961        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14962        // we will switch to the calling user if access to the current user fails.
14963        int targetUserId = unsafeConvertIncomingUser(userId);
14964
14965        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14966            final boolean allow;
14967            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14968                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14969                // If the caller has this permission, they always pass go.  And collect $200.
14970                allow = true;
14971            } else if (allowMode == ALLOW_FULL_ONLY) {
14972                // We require full access, sucks to be you.
14973                allow = false;
14974            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14975                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14976                // If the caller does not have either permission, they are always doomed.
14977                allow = false;
14978            } else if (allowMode == ALLOW_NON_FULL) {
14979                // We are blanket allowing non-full access, you lucky caller!
14980                allow = true;
14981            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14982                // We may or may not allow this depending on whether the two users are
14983                // in the same profile.
14984                synchronized (mUserProfileGroupIdsSelfLocked) {
14985                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14986                            UserInfo.NO_PROFILE_GROUP_ID);
14987                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14988                            UserInfo.NO_PROFILE_GROUP_ID);
14989                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14990                            && callingProfile == targetProfile;
14991                }
14992            } else {
14993                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14994            }
14995            if (!allow) {
14996                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14997                    // In this case, they would like to just execute as their
14998                    // owner user instead of failing.
14999                    targetUserId = callingUserId;
15000                } else {
15001                    StringBuilder builder = new StringBuilder(128);
15002                    builder.append("Permission Denial: ");
15003                    builder.append(name);
15004                    if (callerPackage != null) {
15005                        builder.append(" from ");
15006                        builder.append(callerPackage);
15007                    }
15008                    builder.append(" asks to run as user ");
15009                    builder.append(userId);
15010                    builder.append(" but is calling from user ");
15011                    builder.append(UserHandle.getUserId(callingUid));
15012                    builder.append("; this requires ");
15013                    builder.append(INTERACT_ACROSS_USERS_FULL);
15014                    if (allowMode != ALLOW_FULL_ONLY) {
15015                        builder.append(" or ");
15016                        builder.append(INTERACT_ACROSS_USERS);
15017                    }
15018                    String msg = builder.toString();
15019                    Slog.w(TAG, msg);
15020                    throw new SecurityException(msg);
15021                }
15022            }
15023        }
15024        if (!allowAll && targetUserId < 0) {
15025            throw new IllegalArgumentException(
15026                    "Call does not support special user #" + targetUserId);
15027        }
15028        // Check shell permission
15029        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15030            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15031                    targetUserId)) {
15032                throw new SecurityException("Shell does not have permission to access user "
15033                        + targetUserId + "\n " + Debug.getCallers(3));
15034            }
15035        }
15036        return targetUserId;
15037    }
15038
15039    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15040            String className, int flags) {
15041        boolean result = false;
15042        // For apps that don't have pre-defined UIDs, check for permission
15043        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15044            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15045                if (ActivityManager.checkUidPermission(
15046                        INTERACT_ACROSS_USERS,
15047                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15048                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15049                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15050                            + " requests FLAG_SINGLE_USER, but app does not hold "
15051                            + INTERACT_ACROSS_USERS;
15052                    Slog.w(TAG, msg);
15053                    throw new SecurityException(msg);
15054                }
15055                // Permission passed
15056                result = true;
15057            }
15058        } else if ("system".equals(componentProcessName)) {
15059            result = true;
15060        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15061            // Phone app and persistent apps are allowed to export singleuser providers.
15062            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15063                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15064        }
15065        if (DEBUG_MU) {
15066            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15067                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15068        }
15069        return result;
15070    }
15071
15072    /**
15073     * Checks to see if the caller is in the same app as the singleton
15074     * component, or the component is in a special app. It allows special apps
15075     * to export singleton components but prevents exporting singleton
15076     * components for regular apps.
15077     */
15078    boolean isValidSingletonCall(int callingUid, int componentUid) {
15079        int componentAppId = UserHandle.getAppId(componentUid);
15080        return UserHandle.isSameApp(callingUid, componentUid)
15081                || componentAppId == Process.SYSTEM_UID
15082                || componentAppId == Process.PHONE_UID
15083                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15084                        == PackageManager.PERMISSION_GRANTED;
15085    }
15086
15087    public int bindService(IApplicationThread caller, IBinder token,
15088            Intent service, String resolvedType,
15089            IServiceConnection connection, int flags, int userId) {
15090        enforceNotIsolatedCaller("bindService");
15091
15092        // Refuse possible leaked file descriptors
15093        if (service != null && service.hasFileDescriptors() == true) {
15094            throw new IllegalArgumentException("File descriptors passed in Intent");
15095        }
15096
15097        synchronized(this) {
15098            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15099                    connection, flags, userId);
15100        }
15101    }
15102
15103    public boolean unbindService(IServiceConnection connection) {
15104        synchronized (this) {
15105            return mServices.unbindServiceLocked(connection);
15106        }
15107    }
15108
15109    public void publishService(IBinder token, Intent intent, IBinder service) {
15110        // Refuse possible leaked file descriptors
15111        if (intent != null && intent.hasFileDescriptors() == true) {
15112            throw new IllegalArgumentException("File descriptors passed in Intent");
15113        }
15114
15115        synchronized(this) {
15116            if (!(token instanceof ServiceRecord)) {
15117                throw new IllegalArgumentException("Invalid service token");
15118            }
15119            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15120        }
15121    }
15122
15123    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15124        // Refuse possible leaked file descriptors
15125        if (intent != null && intent.hasFileDescriptors() == true) {
15126            throw new IllegalArgumentException("File descriptors passed in Intent");
15127        }
15128
15129        synchronized(this) {
15130            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15131        }
15132    }
15133
15134    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15135        synchronized(this) {
15136            if (!(token instanceof ServiceRecord)) {
15137                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15138                throw new IllegalArgumentException("Invalid service token");
15139            }
15140            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15141        }
15142    }
15143
15144    // =========================================================
15145    // BACKUP AND RESTORE
15146    // =========================================================
15147
15148    // Cause the target app to be launched if necessary and its backup agent
15149    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15150    // activity manager to announce its creation.
15151    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15152        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15153                "bindBackupAgent: app=" + app + " mode=" + backupMode);
15154        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15155
15156        synchronized(this) {
15157            // !!! TODO: currently no check here that we're already bound
15158            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15159            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15160            synchronized (stats) {
15161                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15162            }
15163
15164            // Backup agent is now in use, its package can't be stopped.
15165            try {
15166                AppGlobals.getPackageManager().setPackageStoppedState(
15167                        app.packageName, false, UserHandle.getUserId(app.uid));
15168            } catch (RemoteException e) {
15169            } catch (IllegalArgumentException e) {
15170                Slog.w(TAG, "Failed trying to unstop package "
15171                        + app.packageName + ": " + e);
15172            }
15173
15174            BackupRecord r = new BackupRecord(ss, app, backupMode);
15175            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15176                    ? new ComponentName(app.packageName, app.backupAgentName)
15177                    : new ComponentName("android", "FullBackupAgent");
15178            // startProcessLocked() returns existing proc's record if it's already running
15179            ProcessRecord proc = startProcessLocked(app.processName, app,
15180                    false, 0, "backup", hostingName, false, false, false);
15181            if (proc == null) {
15182                Slog.e(TAG, "Unable to start backup agent process " + r);
15183                return false;
15184            }
15185
15186            r.app = proc;
15187            mBackupTarget = r;
15188            mBackupAppName = app.packageName;
15189
15190            // Try not to kill the process during backup
15191            updateOomAdjLocked(proc);
15192
15193            // If the process is already attached, schedule the creation of the backup agent now.
15194            // If it is not yet live, this will be done when it attaches to the framework.
15195            if (proc.thread != null) {
15196                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
15197                try {
15198                    proc.thread.scheduleCreateBackupAgent(app,
15199                            compatibilityInfoForPackageLocked(app), backupMode);
15200                } catch (RemoteException e) {
15201                    // Will time out on the backup manager side
15202                }
15203            } else {
15204                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
15205            }
15206            // Invariants: at this point, the target app process exists and the application
15207            // is either already running or in the process of coming up.  mBackupTarget and
15208            // mBackupAppName describe the app, so that when it binds back to the AM we
15209            // know that it's scheduled for a backup-agent operation.
15210        }
15211
15212        return true;
15213    }
15214
15215    @Override
15216    public void clearPendingBackup() {
15217        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
15218        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15219
15220        synchronized (this) {
15221            mBackupTarget = null;
15222            mBackupAppName = null;
15223        }
15224    }
15225
15226    // A backup agent has just come up
15227    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15228        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
15229                + " = " + agent);
15230
15231        synchronized(this) {
15232            if (!agentPackageName.equals(mBackupAppName)) {
15233                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15234                return;
15235            }
15236        }
15237
15238        long oldIdent = Binder.clearCallingIdentity();
15239        try {
15240            IBackupManager bm = IBackupManager.Stub.asInterface(
15241                    ServiceManager.getService(Context.BACKUP_SERVICE));
15242            bm.agentConnected(agentPackageName, agent);
15243        } catch (RemoteException e) {
15244            // can't happen; the backup manager service is local
15245        } catch (Exception e) {
15246            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15247            e.printStackTrace();
15248        } finally {
15249            Binder.restoreCallingIdentity(oldIdent);
15250        }
15251    }
15252
15253    // done with this agent
15254    public void unbindBackupAgent(ApplicationInfo appInfo) {
15255        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
15256        if (appInfo == null) {
15257            Slog.w(TAG, "unbind backup agent for null app");
15258            return;
15259        }
15260
15261        synchronized(this) {
15262            try {
15263                if (mBackupAppName == null) {
15264                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15265                    return;
15266                }
15267
15268                if (!mBackupAppName.equals(appInfo.packageName)) {
15269                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15270                    return;
15271                }
15272
15273                // Not backing this app up any more; reset its OOM adjustment
15274                final ProcessRecord proc = mBackupTarget.app;
15275                updateOomAdjLocked(proc);
15276
15277                // If the app crashed during backup, 'thread' will be null here
15278                if (proc.thread != null) {
15279                    try {
15280                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15281                                compatibilityInfoForPackageLocked(appInfo));
15282                    } catch (Exception e) {
15283                        Slog.e(TAG, "Exception when unbinding backup agent:");
15284                        e.printStackTrace();
15285                    }
15286                }
15287            } finally {
15288                mBackupTarget = null;
15289                mBackupAppName = null;
15290            }
15291        }
15292    }
15293    // =========================================================
15294    // BROADCASTS
15295    // =========================================================
15296
15297    boolean isPendingBroadcastProcessLocked(int pid) {
15298        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15299                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15300    }
15301
15302    void skipPendingBroadcastLocked(int pid) {
15303            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15304            for (BroadcastQueue queue : mBroadcastQueues) {
15305                queue.skipPendingBroadcastLocked(pid);
15306            }
15307    }
15308
15309    // The app just attached; send any pending broadcasts that it should receive
15310    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15311        boolean didSomething = false;
15312        for (BroadcastQueue queue : mBroadcastQueues) {
15313            didSomething |= queue.sendPendingBroadcastsLocked(app);
15314        }
15315        return didSomething;
15316    }
15317
15318    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15319            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15320        enforceNotIsolatedCaller("registerReceiver");
15321        ArrayList<Intent> stickyIntents = null;
15322        ProcessRecord callerApp = null;
15323        int callingUid;
15324        int callingPid;
15325        synchronized(this) {
15326            if (caller != null) {
15327                callerApp = getRecordForAppLocked(caller);
15328                if (callerApp == null) {
15329                    throw new SecurityException(
15330                            "Unable to find app for caller " + caller
15331                            + " (pid=" + Binder.getCallingPid()
15332                            + ") when registering receiver " + receiver);
15333                }
15334                if (callerApp.info.uid != Process.SYSTEM_UID &&
15335                        !callerApp.pkgList.containsKey(callerPackage) &&
15336                        !"android".equals(callerPackage)) {
15337                    throw new SecurityException("Given caller package " + callerPackage
15338                            + " is not running in process " + callerApp);
15339                }
15340                callingUid = callerApp.info.uid;
15341                callingPid = callerApp.pid;
15342            } else {
15343                callerPackage = null;
15344                callingUid = Binder.getCallingUid();
15345                callingPid = Binder.getCallingPid();
15346            }
15347
15348            userId = handleIncomingUser(callingPid, callingUid, userId,
15349                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15350
15351            Iterator<String> actions = filter.actionsIterator();
15352            if (actions == null) {
15353                ArrayList<String> noAction = new ArrayList<String>(1);
15354                noAction.add(null);
15355                actions = noAction.iterator();
15356            }
15357
15358            // Collect stickies of users
15359            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
15360            while (actions.hasNext()) {
15361                String action = actions.next();
15362                for (int id : userIds) {
15363                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
15364                    if (stickies != null) {
15365                        ArrayList<Intent> intents = stickies.get(action);
15366                        if (intents != null) {
15367                            if (stickyIntents == null) {
15368                                stickyIntents = new ArrayList<Intent>();
15369                            }
15370                            stickyIntents.addAll(intents);
15371                        }
15372                    }
15373                }
15374            }
15375        }
15376
15377        ArrayList<Intent> allSticky = null;
15378        if (stickyIntents != null) {
15379            final ContentResolver resolver = mContext.getContentResolver();
15380            // Look for any matching sticky broadcasts...
15381            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
15382                Intent intent = stickyIntents.get(i);
15383                // If intent has scheme "content", it will need to acccess
15384                // provider that needs to lock mProviderMap in ActivityThread
15385                // and also it may need to wait application response, so we
15386                // cannot lock ActivityManagerService here.
15387                if (filter.match(resolver, intent, true, TAG) >= 0) {
15388                    if (allSticky == null) {
15389                        allSticky = new ArrayList<Intent>();
15390                    }
15391                    allSticky.add(intent);
15392                }
15393            }
15394        }
15395
15396        // The first sticky in the list is returned directly back to the client.
15397        Intent sticky = allSticky != null ? allSticky.get(0) : null;
15398        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
15399        if (receiver == null) {
15400            return sticky;
15401        }
15402
15403        synchronized (this) {
15404            if (callerApp != null && callerApp.pid == 0) {
15405                // Caller already died
15406                return null;
15407            }
15408            ReceiverList rl
15409                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15410            if (rl == null) {
15411                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15412                        userId, receiver);
15413                if (rl.app != null) {
15414                    rl.app.receivers.add(rl);
15415                } else {
15416                    try {
15417                        receiver.asBinder().linkToDeath(rl, 0);
15418                    } catch (RemoteException e) {
15419                        return sticky;
15420                    }
15421                    rl.linkedToDeath = true;
15422                }
15423                mRegisteredReceivers.put(receiver.asBinder(), rl);
15424            } else if (rl.uid != callingUid) {
15425                throw new IllegalArgumentException(
15426                        "Receiver requested to register for uid " + callingUid
15427                        + " was previously registered for uid " + rl.uid);
15428            } else if (rl.pid != callingPid) {
15429                throw new IllegalArgumentException(
15430                        "Receiver requested to register for pid " + callingPid
15431                        + " was previously registered for pid " + rl.pid);
15432            } else if (rl.userId != userId) {
15433                throw new IllegalArgumentException(
15434                        "Receiver requested to register for user " + userId
15435                        + " was previously registered for user " + rl.userId);
15436            }
15437            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15438                    permission, callingUid, userId);
15439            rl.add(bf);
15440            if (!bf.debugCheck()) {
15441                Slog.w(TAG, "==> For Dynamic broadast");
15442            }
15443            mReceiverResolver.addFilter(bf);
15444
15445            // Enqueue broadcasts for all existing stickies that match
15446            // this filter.
15447            if (allSticky != null) {
15448                ArrayList receivers = new ArrayList();
15449                receivers.add(bf);
15450
15451                int N = allSticky.size();
15452                for (int i=0; i<N; i++) {
15453                    Intent intent = (Intent)allSticky.get(i);
15454                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15455                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15456                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15457                            null, null, false, true, true, -1);
15458                    queue.enqueueParallelBroadcastLocked(r);
15459                    queue.scheduleBroadcastsLocked();
15460                }
15461            }
15462
15463            return sticky;
15464        }
15465    }
15466
15467    public void unregisterReceiver(IIntentReceiver receiver) {
15468        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
15469
15470        final long origId = Binder.clearCallingIdentity();
15471        try {
15472            boolean doTrim = false;
15473
15474            synchronized(this) {
15475                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15476                if (rl != null) {
15477                    final BroadcastRecord r = rl.curBroadcast;
15478                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
15479                        final boolean doNext = r.queue.finishReceiverLocked(
15480                                r, r.resultCode, r.resultData, r.resultExtras,
15481                                r.resultAbort, false);
15482                        if (doNext) {
15483                            doTrim = true;
15484                            r.queue.processNextBroadcast(false);
15485                        }
15486                    }
15487
15488                    if (rl.app != null) {
15489                        rl.app.receivers.remove(rl);
15490                    }
15491                    removeReceiverLocked(rl);
15492                    if (rl.linkedToDeath) {
15493                        rl.linkedToDeath = false;
15494                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15495                    }
15496                }
15497            }
15498
15499            // If we actually concluded any broadcasts, we might now be able
15500            // to trim the recipients' apps from our working set
15501            if (doTrim) {
15502                trimApplications();
15503                return;
15504            }
15505
15506        } finally {
15507            Binder.restoreCallingIdentity(origId);
15508        }
15509    }
15510
15511    void removeReceiverLocked(ReceiverList rl) {
15512        mRegisteredReceivers.remove(rl.receiver.asBinder());
15513        int N = rl.size();
15514        for (int i=0; i<N; i++) {
15515            mReceiverResolver.removeFilter(rl.get(i));
15516        }
15517    }
15518
15519    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15520        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15521            ProcessRecord r = mLruProcesses.get(i);
15522            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15523                try {
15524                    r.thread.dispatchPackageBroadcast(cmd, packages);
15525                } catch (RemoteException ex) {
15526                }
15527            }
15528        }
15529    }
15530
15531    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15532            int callingUid, int[] users) {
15533        List<ResolveInfo> receivers = null;
15534        try {
15535            HashSet<ComponentName> singleUserReceivers = null;
15536            boolean scannedFirstReceivers = false;
15537            for (int user : users) {
15538                // Skip users that have Shell restrictions
15539                if (callingUid == Process.SHELL_UID
15540                        && getUserManagerLocked().hasUserRestriction(
15541                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15542                    continue;
15543                }
15544                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15545                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15546                if (user != 0 && newReceivers != null) {
15547                    // If this is not the primary user, we need to check for
15548                    // any receivers that should be filtered out.
15549                    for (int i=0; i<newReceivers.size(); i++) {
15550                        ResolveInfo ri = newReceivers.get(i);
15551                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15552                            newReceivers.remove(i);
15553                            i--;
15554                        }
15555                    }
15556                }
15557                if (newReceivers != null && newReceivers.size() == 0) {
15558                    newReceivers = null;
15559                }
15560                if (receivers == null) {
15561                    receivers = newReceivers;
15562                } else if (newReceivers != null) {
15563                    // We need to concatenate the additional receivers
15564                    // found with what we have do far.  This would be easy,
15565                    // but we also need to de-dup any receivers that are
15566                    // singleUser.
15567                    if (!scannedFirstReceivers) {
15568                        // Collect any single user receivers we had already retrieved.
15569                        scannedFirstReceivers = true;
15570                        for (int i=0; i<receivers.size(); i++) {
15571                            ResolveInfo ri = receivers.get(i);
15572                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15573                                ComponentName cn = new ComponentName(
15574                                        ri.activityInfo.packageName, ri.activityInfo.name);
15575                                if (singleUserReceivers == null) {
15576                                    singleUserReceivers = new HashSet<ComponentName>();
15577                                }
15578                                singleUserReceivers.add(cn);
15579                            }
15580                        }
15581                    }
15582                    // Add the new results to the existing results, tracking
15583                    // and de-dupping single user receivers.
15584                    for (int i=0; i<newReceivers.size(); i++) {
15585                        ResolveInfo ri = newReceivers.get(i);
15586                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15587                            ComponentName cn = new ComponentName(
15588                                    ri.activityInfo.packageName, ri.activityInfo.name);
15589                            if (singleUserReceivers == null) {
15590                                singleUserReceivers = new HashSet<ComponentName>();
15591                            }
15592                            if (!singleUserReceivers.contains(cn)) {
15593                                singleUserReceivers.add(cn);
15594                                receivers.add(ri);
15595                            }
15596                        } else {
15597                            receivers.add(ri);
15598                        }
15599                    }
15600                }
15601            }
15602        } catch (RemoteException ex) {
15603            // pm is in same process, this will never happen.
15604        }
15605        return receivers;
15606    }
15607
15608    private final int broadcastIntentLocked(ProcessRecord callerApp,
15609            String callerPackage, Intent intent, String resolvedType,
15610            IIntentReceiver resultTo, int resultCode, String resultData,
15611            Bundle map, String requiredPermission, int appOp,
15612            boolean ordered, boolean sticky, int callingPid, int callingUid,
15613            int userId) {
15614        intent = new Intent(intent);
15615
15616        // By default broadcasts do not go to stopped apps.
15617        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15618
15619        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
15620                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15621                + " ordered=" + ordered + " userid=" + userId);
15622        if ((resultTo != null) && !ordered) {
15623            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15624        }
15625
15626        userId = handleIncomingUser(callingPid, callingUid, userId,
15627                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15628
15629        // Make sure that the user who is receiving this broadcast is running.
15630        // If not, we will just skip it. Make an exception for shutdown broadcasts
15631        // and upgrade steps.
15632
15633        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15634            if ((callingUid != Process.SYSTEM_UID
15635                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15636                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15637                Slog.w(TAG, "Skipping broadcast of " + intent
15638                        + ": user " + userId + " is stopped");
15639                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15640            }
15641        }
15642
15643        /*
15644         * Prevent non-system code (defined here to be non-persistent
15645         * processes) from sending protected broadcasts.
15646         */
15647        int callingAppId = UserHandle.getAppId(callingUid);
15648        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15649            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15650            || callingAppId == Process.NFC_UID || callingUid == 0) {
15651            // Always okay.
15652        } else if (callerApp == null || !callerApp.persistent) {
15653            try {
15654                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15655                        intent.getAction())) {
15656                    String msg = "Permission Denial: not allowed to send broadcast "
15657                            + intent.getAction() + " from pid="
15658                            + callingPid + ", uid=" + callingUid;
15659                    Slog.w(TAG, msg);
15660                    throw new SecurityException(msg);
15661                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15662                    // Special case for compatibility: we don't want apps to send this,
15663                    // but historically it has not been protected and apps may be using it
15664                    // to poke their own app widget.  So, instead of making it protected,
15665                    // just limit it to the caller.
15666                    if (callerApp == null) {
15667                        String msg = "Permission Denial: not allowed to send broadcast "
15668                                + intent.getAction() + " from unknown caller.";
15669                        Slog.w(TAG, msg);
15670                        throw new SecurityException(msg);
15671                    } else if (intent.getComponent() != null) {
15672                        // They are good enough to send to an explicit component...  verify
15673                        // it is being sent to the calling app.
15674                        if (!intent.getComponent().getPackageName().equals(
15675                                callerApp.info.packageName)) {
15676                            String msg = "Permission Denial: not allowed to send broadcast "
15677                                    + intent.getAction() + " to "
15678                                    + intent.getComponent().getPackageName() + " from "
15679                                    + callerApp.info.packageName;
15680                            Slog.w(TAG, msg);
15681                            throw new SecurityException(msg);
15682                        }
15683                    } else {
15684                        // Limit broadcast to their own package.
15685                        intent.setPackage(callerApp.info.packageName);
15686                    }
15687                }
15688            } catch (RemoteException e) {
15689                Slog.w(TAG, "Remote exception", e);
15690                return ActivityManager.BROADCAST_SUCCESS;
15691            }
15692        }
15693
15694        final String action = intent.getAction();
15695        if (action != null) {
15696            switch (action) {
15697                case Intent.ACTION_UID_REMOVED:
15698                case Intent.ACTION_PACKAGE_REMOVED:
15699                case Intent.ACTION_PACKAGE_CHANGED:
15700                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15701                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15702                    // Handle special intents: if this broadcast is from the package
15703                    // manager about a package being removed, we need to remove all of
15704                    // its activities from the history stack.
15705                    if (checkComponentPermission(
15706                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15707                            callingPid, callingUid, -1, true)
15708                            != PackageManager.PERMISSION_GRANTED) {
15709                        String msg = "Permission Denial: " + intent.getAction()
15710                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15711                                + ", uid=" + callingUid + ")"
15712                                + " requires "
15713                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15714                        Slog.w(TAG, msg);
15715                        throw new SecurityException(msg);
15716                    }
15717                    switch (action) {
15718                        case Intent.ACTION_UID_REMOVED:
15719                            final Bundle intentExtras = intent.getExtras();
15720                            final int uid = intentExtras != null
15721                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15722                            if (uid >= 0) {
15723                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15724                                synchronized (bs) {
15725                                    bs.removeUidStatsLocked(uid);
15726                                }
15727                                mAppOpsService.uidRemoved(uid);
15728                            }
15729                            break;
15730                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15731                            // If resources are unavailable just force stop all those packages
15732                            // and flush the attribute cache as well.
15733                            String list[] =
15734                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15735                            if (list != null && list.length > 0) {
15736                                for (int i = 0; i < list.length; i++) {
15737                                    forceStopPackageLocked(list[i], -1, false, true, true,
15738                                            false, false, userId, "storage unmount");
15739                                }
15740                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
15741                                sendPackageBroadcastLocked(
15742                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15743                                        userId);
15744                            }
15745                            break;
15746                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15747                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
15748                            break;
15749                        case Intent.ACTION_PACKAGE_REMOVED:
15750                        case Intent.ACTION_PACKAGE_CHANGED:
15751                            Uri data = intent.getData();
15752                            String ssp;
15753                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15754                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15755                                boolean fullUninstall = removed &&
15756                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15757                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15758                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15759                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15760                                            false, true, true, false, fullUninstall, userId,
15761                                            removed ? "pkg removed" : "pkg changed");
15762                                }
15763                                if (removed) {
15764                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15765                                            new String[] {ssp}, userId);
15766                                    if (fullUninstall) {
15767                                        mAppOpsService.packageRemoved(
15768                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15769
15770                                        // Remove all permissions granted from/to this package
15771                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15772
15773                                        removeTasksByPackageNameLocked(ssp, userId);
15774                                        if (userId == UserHandle.USER_OWNER) {
15775                                            mTaskPersister.removeFromPackageCache(ssp);
15776                                        }
15777                                    }
15778                                } else {
15779                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15780                                    if (userId == UserHandle.USER_OWNER) {
15781                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15782                                    }
15783                                }
15784                            }
15785                            break;
15786                    }
15787                    break;
15788                case Intent.ACTION_PACKAGE_ADDED:
15789                    // Special case for adding a package: by default turn on compatibility mode.
15790                    Uri data = intent.getData();
15791                    String ssp;
15792                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15793                        final boolean replacing =
15794                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15795                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15796
15797                        if (replacing) {
15798                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15799                        }
15800                        if (userId == UserHandle.USER_OWNER) {
15801                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15802                        }
15803                    }
15804                    break;
15805                case Intent.ACTION_TIMEZONE_CHANGED:
15806                    // If this is the time zone changed action, queue up a message that will reset
15807                    // the timezone of all currently running processes. This message will get
15808                    // queued up before the broadcast happens.
15809                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15810                    break;
15811                case Intent.ACTION_TIME_CHANGED:
15812                    // If the user set the time, let all running processes know.
15813                    final int is24Hour =
15814                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15815                                    : 0;
15816                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15817                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15818                    synchronized (stats) {
15819                        stats.noteCurrentTimeChangedLocked();
15820                    }
15821                    break;
15822                case Intent.ACTION_CLEAR_DNS_CACHE:
15823                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15824                    break;
15825                case Proxy.PROXY_CHANGE_ACTION:
15826                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15827                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15828                    break;
15829            }
15830        }
15831
15832        // Add to the sticky list if requested.
15833        if (sticky) {
15834            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15835                    callingPid, callingUid)
15836                    != PackageManager.PERMISSION_GRANTED) {
15837                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15838                        + callingPid + ", uid=" + callingUid
15839                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15840                Slog.w(TAG, msg);
15841                throw new SecurityException(msg);
15842            }
15843            if (requiredPermission != null) {
15844                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15845                        + " and enforce permission " + requiredPermission);
15846                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15847            }
15848            if (intent.getComponent() != null) {
15849                throw new SecurityException(
15850                        "Sticky broadcasts can't target a specific component");
15851            }
15852            // We use userId directly here, since the "all" target is maintained
15853            // as a separate set of sticky broadcasts.
15854            if (userId != UserHandle.USER_ALL) {
15855                // But first, if this is not a broadcast to all users, then
15856                // make sure it doesn't conflict with an existing broadcast to
15857                // all users.
15858                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15859                        UserHandle.USER_ALL);
15860                if (stickies != null) {
15861                    ArrayList<Intent> list = stickies.get(intent.getAction());
15862                    if (list != null) {
15863                        int N = list.size();
15864                        int i;
15865                        for (i=0; i<N; i++) {
15866                            if (intent.filterEquals(list.get(i))) {
15867                                throw new IllegalArgumentException(
15868                                        "Sticky broadcast " + intent + " for user "
15869                                        + userId + " conflicts with existing global broadcast");
15870                            }
15871                        }
15872                    }
15873                }
15874            }
15875            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15876            if (stickies == null) {
15877                stickies = new ArrayMap<String, ArrayList<Intent>>();
15878                mStickyBroadcasts.put(userId, stickies);
15879            }
15880            ArrayList<Intent> list = stickies.get(intent.getAction());
15881            if (list == null) {
15882                list = new ArrayList<Intent>();
15883                stickies.put(intent.getAction(), list);
15884            }
15885            int N = list.size();
15886            int i;
15887            for (i=0; i<N; i++) {
15888                if (intent.filterEquals(list.get(i))) {
15889                    // This sticky already exists, replace it.
15890                    list.set(i, new Intent(intent));
15891                    break;
15892                }
15893            }
15894            if (i >= N) {
15895                list.add(new Intent(intent));
15896            }
15897        }
15898
15899        int[] users;
15900        if (userId == UserHandle.USER_ALL) {
15901            // Caller wants broadcast to go to all started users.
15902            users = mStartedUserArray;
15903        } else {
15904            // Caller wants broadcast to go to one specific user.
15905            users = new int[] {userId};
15906        }
15907
15908        // Figure out who all will receive this broadcast.
15909        List receivers = null;
15910        List<BroadcastFilter> registeredReceivers = null;
15911        // Need to resolve the intent to interested receivers...
15912        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15913                 == 0) {
15914            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15915        }
15916        if (intent.getComponent() == null) {
15917            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15918                // Query one target user at a time, excluding shell-restricted users
15919                UserManagerService ums = getUserManagerLocked();
15920                for (int i = 0; i < users.length; i++) {
15921                    if (ums.hasUserRestriction(
15922                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15923                        continue;
15924                    }
15925                    List<BroadcastFilter> registeredReceiversForUser =
15926                            mReceiverResolver.queryIntent(intent,
15927                                    resolvedType, false, users[i]);
15928                    if (registeredReceivers == null) {
15929                        registeredReceivers = registeredReceiversForUser;
15930                    } else if (registeredReceiversForUser != null) {
15931                        registeredReceivers.addAll(registeredReceiversForUser);
15932                    }
15933                }
15934            } else {
15935                registeredReceivers = mReceiverResolver.queryIntent(intent,
15936                        resolvedType, false, userId);
15937            }
15938        }
15939
15940        final boolean replacePending =
15941                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15942
15943        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
15944                + " replacePending=" + replacePending);
15945
15946        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15947        if (!ordered && NR > 0) {
15948            // If we are not serializing this broadcast, then send the
15949            // registered receivers separately so they don't wait for the
15950            // components to be launched.
15951            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15952            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15953                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15954                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15955                    ordered, sticky, false, userId);
15956            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
15957            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15958            if (!replaced) {
15959                queue.enqueueParallelBroadcastLocked(r);
15960                queue.scheduleBroadcastsLocked();
15961            }
15962            registeredReceivers = null;
15963            NR = 0;
15964        }
15965
15966        // Merge into one list.
15967        int ir = 0;
15968        if (receivers != null) {
15969            // A special case for PACKAGE_ADDED: do not allow the package
15970            // being added to see this broadcast.  This prevents them from
15971            // using this as a back door to get run as soon as they are
15972            // installed.  Maybe in the future we want to have a special install
15973            // broadcast or such for apps, but we'd like to deliberately make
15974            // this decision.
15975            String skipPackages[] = null;
15976            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15977                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15978                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15979                Uri data = intent.getData();
15980                if (data != null) {
15981                    String pkgName = data.getSchemeSpecificPart();
15982                    if (pkgName != null) {
15983                        skipPackages = new String[] { pkgName };
15984                    }
15985                }
15986            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15987                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15988            }
15989            if (skipPackages != null && (skipPackages.length > 0)) {
15990                for (String skipPackage : skipPackages) {
15991                    if (skipPackage != null) {
15992                        int NT = receivers.size();
15993                        for (int it=0; it<NT; it++) {
15994                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15995                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15996                                receivers.remove(it);
15997                                it--;
15998                                NT--;
15999                            }
16000                        }
16001                    }
16002                }
16003            }
16004
16005            int NT = receivers != null ? receivers.size() : 0;
16006            int it = 0;
16007            ResolveInfo curt = null;
16008            BroadcastFilter curr = null;
16009            while (it < NT && ir < NR) {
16010                if (curt == null) {
16011                    curt = (ResolveInfo)receivers.get(it);
16012                }
16013                if (curr == null) {
16014                    curr = registeredReceivers.get(ir);
16015                }
16016                if (curr.getPriority() >= curt.priority) {
16017                    // Insert this broadcast record into the final list.
16018                    receivers.add(it, curr);
16019                    ir++;
16020                    curr = null;
16021                    it++;
16022                    NT++;
16023                } else {
16024                    // Skip to the next ResolveInfo in the final list.
16025                    it++;
16026                    curt = null;
16027                }
16028            }
16029        }
16030        while (ir < NR) {
16031            if (receivers == null) {
16032                receivers = new ArrayList();
16033            }
16034            receivers.add(registeredReceivers.get(ir));
16035            ir++;
16036        }
16037
16038        if ((receivers != null && receivers.size() > 0)
16039                || resultTo != null) {
16040            BroadcastQueue queue = broadcastQueueForIntent(intent);
16041            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16042                    callerPackage, callingPid, callingUid, resolvedType,
16043                    requiredPermission, appOp, receivers, resultTo, resultCode,
16044                    resultData, map, ordered, sticky, false, userId);
16045
16046            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16047                    + ": prev had " + queue.mOrderedBroadcasts.size());
16048            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16049                    "Enqueueing broadcast " + r.intent.getAction());
16050
16051            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16052            if (!replaced) {
16053                queue.enqueueOrderedBroadcastLocked(r);
16054                queue.scheduleBroadcastsLocked();
16055            }
16056        }
16057
16058        return ActivityManager.BROADCAST_SUCCESS;
16059    }
16060
16061    final Intent verifyBroadcastLocked(Intent intent) {
16062        // Refuse possible leaked file descriptors
16063        if (intent != null && intent.hasFileDescriptors() == true) {
16064            throw new IllegalArgumentException("File descriptors passed in Intent");
16065        }
16066
16067        int flags = intent.getFlags();
16068
16069        if (!mProcessesReady) {
16070            // if the caller really truly claims to know what they're doing, go
16071            // ahead and allow the broadcast without launching any receivers
16072            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16073                intent = new Intent(intent);
16074                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16075            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16076                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16077                        + " before boot completion");
16078                throw new IllegalStateException("Cannot broadcast before boot completed");
16079            }
16080        }
16081
16082        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16083            throw new IllegalArgumentException(
16084                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16085        }
16086
16087        return intent;
16088    }
16089
16090    public final int broadcastIntent(IApplicationThread caller,
16091            Intent intent, String resolvedType, IIntentReceiver resultTo,
16092            int resultCode, String resultData, Bundle map,
16093            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16094        enforceNotIsolatedCaller("broadcastIntent");
16095        synchronized(this) {
16096            intent = verifyBroadcastLocked(intent);
16097
16098            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16099            final int callingPid = Binder.getCallingPid();
16100            final int callingUid = Binder.getCallingUid();
16101            final long origId = Binder.clearCallingIdentity();
16102            int res = broadcastIntentLocked(callerApp,
16103                    callerApp != null ? callerApp.info.packageName : null,
16104                    intent, resolvedType, resultTo,
16105                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16106                    callingPid, callingUid, userId);
16107            Binder.restoreCallingIdentity(origId);
16108            return res;
16109        }
16110    }
16111
16112    int broadcastIntentInPackage(String packageName, int uid,
16113            Intent intent, String resolvedType, IIntentReceiver resultTo,
16114            int resultCode, String resultData, Bundle map,
16115            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16116        synchronized(this) {
16117            intent = verifyBroadcastLocked(intent);
16118
16119            final long origId = Binder.clearCallingIdentity();
16120            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16121                    resultTo, resultCode, resultData, map, requiredPermission,
16122                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16123            Binder.restoreCallingIdentity(origId);
16124            return res;
16125        }
16126    }
16127
16128    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16129        // Refuse possible leaked file descriptors
16130        if (intent != null && intent.hasFileDescriptors() == true) {
16131            throw new IllegalArgumentException("File descriptors passed in Intent");
16132        }
16133
16134        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16135                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16136
16137        synchronized(this) {
16138            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16139                    != PackageManager.PERMISSION_GRANTED) {
16140                String msg = "Permission Denial: unbroadcastIntent() from pid="
16141                        + Binder.getCallingPid()
16142                        + ", uid=" + Binder.getCallingUid()
16143                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16144                Slog.w(TAG, msg);
16145                throw new SecurityException(msg);
16146            }
16147            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16148            if (stickies != null) {
16149                ArrayList<Intent> list = stickies.get(intent.getAction());
16150                if (list != null) {
16151                    int N = list.size();
16152                    int i;
16153                    for (i=0; i<N; i++) {
16154                        if (intent.filterEquals(list.get(i))) {
16155                            list.remove(i);
16156                            break;
16157                        }
16158                    }
16159                    if (list.size() <= 0) {
16160                        stickies.remove(intent.getAction());
16161                    }
16162                }
16163                if (stickies.size() <= 0) {
16164                    mStickyBroadcasts.remove(userId);
16165                }
16166            }
16167        }
16168    }
16169
16170    void backgroundServicesFinishedLocked(int userId) {
16171        for (BroadcastQueue queue : mBroadcastQueues) {
16172            queue.backgroundServicesFinishedLocked(userId);
16173        }
16174    }
16175
16176    public void finishReceiver(IBinder who, int resultCode, String resultData,
16177            Bundle resultExtras, boolean resultAbort, int flags) {
16178        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
16179
16180        // Refuse possible leaked file descriptors
16181        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16182            throw new IllegalArgumentException("File descriptors passed in Bundle");
16183        }
16184
16185        final long origId = Binder.clearCallingIdentity();
16186        try {
16187            boolean doNext = false;
16188            BroadcastRecord r;
16189
16190            synchronized(this) {
16191                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16192                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16193                r = queue.getMatchingOrderedReceiver(who);
16194                if (r != null) {
16195                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16196                        resultData, resultExtras, resultAbort, true);
16197                }
16198            }
16199
16200            if (doNext) {
16201                r.queue.processNextBroadcast(false);
16202            }
16203            trimApplications();
16204        } finally {
16205            Binder.restoreCallingIdentity(origId);
16206        }
16207    }
16208
16209    // =========================================================
16210    // INSTRUMENTATION
16211    // =========================================================
16212
16213    public boolean startInstrumentation(ComponentName className,
16214            String profileFile, int flags, Bundle arguments,
16215            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16216            int userId, String abiOverride) {
16217        enforceNotIsolatedCaller("startInstrumentation");
16218        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16219                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16220        // Refuse possible leaked file descriptors
16221        if (arguments != null && arguments.hasFileDescriptors()) {
16222            throw new IllegalArgumentException("File descriptors passed in Bundle");
16223        }
16224
16225        synchronized(this) {
16226            InstrumentationInfo ii = null;
16227            ApplicationInfo ai = null;
16228            try {
16229                ii = mContext.getPackageManager().getInstrumentationInfo(
16230                    className, STOCK_PM_FLAGS);
16231                ai = AppGlobals.getPackageManager().getApplicationInfo(
16232                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16233            } catch (PackageManager.NameNotFoundException e) {
16234            } catch (RemoteException e) {
16235            }
16236            if (ii == null) {
16237                reportStartInstrumentationFailure(watcher, className,
16238                        "Unable to find instrumentation info for: " + className);
16239                return false;
16240            }
16241            if (ai == null) {
16242                reportStartInstrumentationFailure(watcher, className,
16243                        "Unable to find instrumentation target package: " + ii.targetPackage);
16244                return false;
16245            }
16246
16247            int match = mContext.getPackageManager().checkSignatures(
16248                    ii.targetPackage, ii.packageName);
16249            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16250                String msg = "Permission Denial: starting instrumentation "
16251                        + className + " from pid="
16252                        + Binder.getCallingPid()
16253                        + ", uid=" + Binder.getCallingPid()
16254                        + " not allowed because package " + ii.packageName
16255                        + " does not have a signature matching the target "
16256                        + ii.targetPackage;
16257                reportStartInstrumentationFailure(watcher, className, msg);
16258                throw new SecurityException(msg);
16259            }
16260
16261            final long origId = Binder.clearCallingIdentity();
16262            // Instrumentation can kill and relaunch even persistent processes
16263            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16264                    "start instr");
16265            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16266            app.instrumentationClass = className;
16267            app.instrumentationInfo = ai;
16268            app.instrumentationProfileFile = profileFile;
16269            app.instrumentationArguments = arguments;
16270            app.instrumentationWatcher = watcher;
16271            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16272            app.instrumentationResultClass = className;
16273            Binder.restoreCallingIdentity(origId);
16274        }
16275
16276        return true;
16277    }
16278
16279    /**
16280     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16281     * error to the logs, but if somebody is watching, send the report there too.  This enables
16282     * the "am" command to report errors with more information.
16283     *
16284     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16285     * @param cn The component name of the instrumentation.
16286     * @param report The error report.
16287     */
16288    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16289            ComponentName cn, String report) {
16290        Slog.w(TAG, report);
16291        try {
16292            if (watcher != null) {
16293                Bundle results = new Bundle();
16294                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16295                results.putString("Error", report);
16296                watcher.instrumentationStatus(cn, -1, results);
16297            }
16298        } catch (RemoteException e) {
16299            Slog.w(TAG, e);
16300        }
16301    }
16302
16303    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16304        if (app.instrumentationWatcher != null) {
16305            try {
16306                // NOTE:  IInstrumentationWatcher *must* be oneway here
16307                app.instrumentationWatcher.instrumentationFinished(
16308                    app.instrumentationClass,
16309                    resultCode,
16310                    results);
16311            } catch (RemoteException e) {
16312            }
16313        }
16314        if (app.instrumentationUiAutomationConnection != null) {
16315            try {
16316                app.instrumentationUiAutomationConnection.shutdown();
16317            } catch (RemoteException re) {
16318                /* ignore */
16319            }
16320            // Only a UiAutomation can set this flag and now that
16321            // it is finished we make sure it is reset to its default.
16322            mUserIsMonkey = false;
16323        }
16324        app.instrumentationWatcher = null;
16325        app.instrumentationUiAutomationConnection = null;
16326        app.instrumentationClass = null;
16327        app.instrumentationInfo = null;
16328        app.instrumentationProfileFile = null;
16329        app.instrumentationArguments = null;
16330
16331        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16332                "finished inst");
16333    }
16334
16335    public void finishInstrumentation(IApplicationThread target,
16336            int resultCode, Bundle results) {
16337        int userId = UserHandle.getCallingUserId();
16338        // Refuse possible leaked file descriptors
16339        if (results != null && results.hasFileDescriptors()) {
16340            throw new IllegalArgumentException("File descriptors passed in Intent");
16341        }
16342
16343        synchronized(this) {
16344            ProcessRecord app = getRecordForAppLocked(target);
16345            if (app == null) {
16346                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16347                return;
16348            }
16349            final long origId = Binder.clearCallingIdentity();
16350            finishInstrumentationLocked(app, resultCode, results);
16351            Binder.restoreCallingIdentity(origId);
16352        }
16353    }
16354
16355    // =========================================================
16356    // CONFIGURATION
16357    // =========================================================
16358
16359    public ConfigurationInfo getDeviceConfigurationInfo() {
16360        ConfigurationInfo config = new ConfigurationInfo();
16361        synchronized (this) {
16362            config.reqTouchScreen = mConfiguration.touchscreen;
16363            config.reqKeyboardType = mConfiguration.keyboard;
16364            config.reqNavigation = mConfiguration.navigation;
16365            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16366                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16367                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16368            }
16369            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16370                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16371                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16372            }
16373            config.reqGlEsVersion = GL_ES_VERSION;
16374        }
16375        return config;
16376    }
16377
16378    ActivityStack getFocusedStack() {
16379        return mStackSupervisor.getFocusedStack();
16380    }
16381
16382    @Override
16383    public int getFocusedStackId() throws RemoteException {
16384        ActivityStack focusedStack = getFocusedStack();
16385        if (focusedStack != null) {
16386            return focusedStack.getStackId();
16387        }
16388        return -1;
16389    }
16390
16391    public Configuration getConfiguration() {
16392        Configuration ci;
16393        synchronized(this) {
16394            ci = new Configuration(mConfiguration);
16395            ci.userSetLocale = false;
16396        }
16397        return ci;
16398    }
16399
16400    public void updatePersistentConfiguration(Configuration values) {
16401        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16402                "updateConfiguration()");
16403        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16404                "updateConfiguration()");
16405        if (values == null) {
16406            throw new NullPointerException("Configuration must not be null");
16407        }
16408
16409        synchronized(this) {
16410            final long origId = Binder.clearCallingIdentity();
16411            updateConfigurationLocked(values, null, true, false);
16412            Binder.restoreCallingIdentity(origId);
16413        }
16414    }
16415
16416    public void updateConfiguration(Configuration values) {
16417        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16418                "updateConfiguration()");
16419
16420        synchronized(this) {
16421            if (values == null && mWindowManager != null) {
16422                // sentinel: fetch the current configuration from the window manager
16423                values = mWindowManager.computeNewConfiguration();
16424            }
16425
16426            if (mWindowManager != null) {
16427                mProcessList.applyDisplaySize(mWindowManager);
16428            }
16429
16430            final long origId = Binder.clearCallingIdentity();
16431            if (values != null) {
16432                Settings.System.clearConfiguration(values);
16433            }
16434            updateConfigurationLocked(values, null, false, false);
16435            Binder.restoreCallingIdentity(origId);
16436        }
16437    }
16438
16439    /**
16440     * Do either or both things: (1) change the current configuration, and (2)
16441     * make sure the given activity is running with the (now) current
16442     * configuration.  Returns true if the activity has been left running, or
16443     * false if <var>starting</var> is being destroyed to match the new
16444     * configuration.
16445     * @param persistent TODO
16446     */
16447    boolean updateConfigurationLocked(Configuration values,
16448            ActivityRecord starting, boolean persistent, boolean initLocale) {
16449        int changes = 0;
16450
16451        if (values != null) {
16452            Configuration newConfig = new Configuration(mConfiguration);
16453            changes = newConfig.updateFrom(values);
16454            if (changes != 0) {
16455                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16456                    Slog.i(TAG, "Updating configuration to: " + values);
16457                }
16458
16459                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16460
16461                if (!initLocale && values.locale != null && values.userSetLocale) {
16462                    final String languageTag = values.locale.toLanguageTag();
16463                    SystemProperties.set("persist.sys.locale", languageTag);
16464                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
16465                            values.locale));
16466                }
16467
16468                mConfigurationSeq++;
16469                if (mConfigurationSeq <= 0) {
16470                    mConfigurationSeq = 1;
16471                }
16472                newConfig.seq = mConfigurationSeq;
16473                mConfiguration = newConfig;
16474                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16475                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16476                //mUsageStatsService.noteStartConfig(newConfig);
16477
16478                final Configuration configCopy = new Configuration(mConfiguration);
16479
16480                // TODO: If our config changes, should we auto dismiss any currently
16481                // showing dialogs?
16482                mShowDialogs = shouldShowDialogs(newConfig);
16483
16484                AttributeCache ac = AttributeCache.instance();
16485                if (ac != null) {
16486                    ac.updateConfiguration(configCopy);
16487                }
16488
16489                // Make sure all resources in our process are updated
16490                // right now, so that anyone who is going to retrieve
16491                // resource values after we return will be sure to get
16492                // the new ones.  This is especially important during
16493                // boot, where the first config change needs to guarantee
16494                // all resources have that config before following boot
16495                // code is executed.
16496                mSystemThread.applyConfigurationToResources(configCopy);
16497
16498                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16499                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16500                    msg.obj = new Configuration(configCopy);
16501                    mHandler.sendMessage(msg);
16502                }
16503
16504                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16505                    ProcessRecord app = mLruProcesses.get(i);
16506                    try {
16507                        if (app.thread != null) {
16508                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16509                                    + app.processName + " new config " + mConfiguration);
16510                            app.thread.scheduleConfigurationChanged(configCopy);
16511                        }
16512                    } catch (Exception e) {
16513                    }
16514                }
16515                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16516                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16517                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16518                        | Intent.FLAG_RECEIVER_FOREGROUND);
16519                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16520                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16521                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16522                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16523                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16524                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16525                    broadcastIntentLocked(null, null, intent,
16526                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16527                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16528                }
16529            }
16530        }
16531
16532        boolean kept = true;
16533        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16534        // mainStack is null during startup.
16535        if (mainStack != null) {
16536            if (changes != 0 && starting == null) {
16537                // If the configuration changed, and the caller is not already
16538                // in the process of starting an activity, then find the top
16539                // activity to check if its configuration needs to change.
16540                starting = mainStack.topRunningActivityLocked(null);
16541            }
16542
16543            if (starting != null) {
16544                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16545                // And we need to make sure at this point that all other activities
16546                // are made visible with the correct configuration.
16547                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16548            }
16549        }
16550
16551        if (values != null && mWindowManager != null) {
16552            mWindowManager.setNewConfiguration(mConfiguration);
16553        }
16554
16555        return kept;
16556    }
16557
16558    /**
16559     * Decide based on the configuration whether we should shouw the ANR,
16560     * crash, etc dialogs.  The idea is that if there is no affordnace to
16561     * press the on-screen buttons, we shouldn't show the dialog.
16562     *
16563     * A thought: SystemUI might also want to get told about this, the Power
16564     * dialog / global actions also might want different behaviors.
16565     */
16566    private static final boolean shouldShowDialogs(Configuration config) {
16567        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16568                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
16569                && config.navigation == Configuration.NAVIGATION_NONAV);
16570    }
16571
16572    @Override
16573    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16574        synchronized (this) {
16575            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
16576            if (srec != null) {
16577                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16578            }
16579        }
16580        return false;
16581    }
16582
16583    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16584            Intent resultData) {
16585
16586        synchronized (this) {
16587            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
16588            if (r != null) {
16589                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
16590            }
16591            return false;
16592        }
16593    }
16594
16595    public int getLaunchedFromUid(IBinder activityToken) {
16596        ActivityRecord srec;
16597        synchronized (this) {
16598            srec = ActivityRecord.forTokenLocked(activityToken);
16599        }
16600        if (srec == null) {
16601            return -1;
16602        }
16603        return srec.launchedFromUid;
16604    }
16605
16606    public String getLaunchedFromPackage(IBinder activityToken) {
16607        ActivityRecord srec;
16608        synchronized (this) {
16609            srec = ActivityRecord.forTokenLocked(activityToken);
16610        }
16611        if (srec == null) {
16612            return null;
16613        }
16614        return srec.launchedFromPackage;
16615    }
16616
16617    // =========================================================
16618    // LIFETIME MANAGEMENT
16619    // =========================================================
16620
16621    // Returns which broadcast queue the app is the current [or imminent] receiver
16622    // on, or 'null' if the app is not an active broadcast recipient.
16623    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16624        BroadcastRecord r = app.curReceiver;
16625        if (r != null) {
16626            return r.queue;
16627        }
16628
16629        // It's not the current receiver, but it might be starting up to become one
16630        synchronized (this) {
16631            for (BroadcastQueue queue : mBroadcastQueues) {
16632                r = queue.mPendingBroadcast;
16633                if (r != null && r.curApp == app) {
16634                    // found it; report which queue it's in
16635                    return queue;
16636                }
16637            }
16638        }
16639
16640        return null;
16641    }
16642
16643    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16644            ComponentName targetComponent, String targetProcess) {
16645        if (!mTrackingAssociations) {
16646            return null;
16647        }
16648        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16649                = mAssociations.get(targetUid);
16650        if (components == null) {
16651            components = new ArrayMap<>();
16652            mAssociations.put(targetUid, components);
16653        }
16654        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16655        if (sourceUids == null) {
16656            sourceUids = new SparseArray<>();
16657            components.put(targetComponent, sourceUids);
16658        }
16659        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16660        if (sourceProcesses == null) {
16661            sourceProcesses = new ArrayMap<>();
16662            sourceUids.put(sourceUid, sourceProcesses);
16663        }
16664        Association ass = sourceProcesses.get(sourceProcess);
16665        if (ass == null) {
16666            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
16667                    targetProcess);
16668            sourceProcesses.put(sourceProcess, ass);
16669        }
16670        ass.mCount++;
16671        ass.mNesting++;
16672        if (ass.mNesting == 1) {
16673            ass.mStartTime = SystemClock.uptimeMillis();
16674        }
16675        return ass;
16676    }
16677
16678    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16679            ComponentName targetComponent) {
16680        if (!mTrackingAssociations) {
16681            return;
16682        }
16683        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16684                = mAssociations.get(targetUid);
16685        if (components == null) {
16686            return;
16687        }
16688        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16689        if (sourceUids == null) {
16690            return;
16691        }
16692        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16693        if (sourceProcesses == null) {
16694            return;
16695        }
16696        Association ass = sourceProcesses.get(sourceProcess);
16697        if (ass == null || ass.mNesting <= 0) {
16698            return;
16699        }
16700        ass.mNesting--;
16701        if (ass.mNesting == 0) {
16702            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
16703        }
16704    }
16705
16706    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16707            boolean doingAll, long now) {
16708        if (mAdjSeq == app.adjSeq) {
16709            // This adjustment has already been computed.
16710            return app.curRawAdj;
16711        }
16712
16713        if (app.thread == null) {
16714            app.adjSeq = mAdjSeq;
16715            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16716            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16717            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16718        }
16719
16720        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16721        app.adjSource = null;
16722        app.adjTarget = null;
16723        app.empty = false;
16724        app.cached = false;
16725
16726        final int activitiesSize = app.activities.size();
16727
16728        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16729            // The max adjustment doesn't allow this app to be anything
16730            // below foreground, so it is not worth doing work for it.
16731            app.adjType = "fixed";
16732            app.adjSeq = mAdjSeq;
16733            app.curRawAdj = app.maxAdj;
16734            app.foregroundActivities = false;
16735            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16736            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16737            // System processes can do UI, and when they do we want to have
16738            // them trim their memory after the user leaves the UI.  To
16739            // facilitate this, here we need to determine whether or not it
16740            // is currently showing UI.
16741            app.systemNoUi = true;
16742            if (app == TOP_APP) {
16743                app.systemNoUi = false;
16744            } else if (activitiesSize > 0) {
16745                for (int j = 0; j < activitiesSize; j++) {
16746                    final ActivityRecord r = app.activities.get(j);
16747                    if (r.visible) {
16748                        app.systemNoUi = false;
16749                    }
16750                }
16751            }
16752            if (!app.systemNoUi) {
16753                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16754            }
16755            return (app.curAdj=app.maxAdj);
16756        }
16757
16758        app.systemNoUi = false;
16759
16760        // Determine the importance of the process, starting with most
16761        // important to least, and assign an appropriate OOM adjustment.
16762        int adj;
16763        int schedGroup;
16764        int procState;
16765        boolean foregroundActivities = false;
16766        BroadcastQueue queue;
16767        if (app == TOP_APP) {
16768            // The last app on the list is the foreground app.
16769            adj = ProcessList.FOREGROUND_APP_ADJ;
16770            schedGroup = Process.THREAD_GROUP_DEFAULT;
16771            app.adjType = "top-activity";
16772            foregroundActivities = true;
16773            procState = ActivityManager.PROCESS_STATE_TOP;
16774        } else if (app.instrumentationClass != null) {
16775            // Don't want to kill running instrumentation.
16776            adj = ProcessList.FOREGROUND_APP_ADJ;
16777            schedGroup = Process.THREAD_GROUP_DEFAULT;
16778            app.adjType = "instrumentation";
16779            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16780        } else if ((queue = isReceivingBroadcast(app)) != null) {
16781            // An app that is currently receiving a broadcast also
16782            // counts as being in the foreground for OOM killer purposes.
16783            // It's placed in a sched group based on the nature of the
16784            // broadcast as reflected by which queue it's active in.
16785            adj = ProcessList.FOREGROUND_APP_ADJ;
16786            schedGroup = (queue == mFgBroadcastQueue)
16787                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16788            app.adjType = "broadcast";
16789            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16790        } else if (app.executingServices.size() > 0) {
16791            // An app that is currently executing a service callback also
16792            // counts as being in the foreground.
16793            adj = ProcessList.FOREGROUND_APP_ADJ;
16794            schedGroup = app.execServicesFg ?
16795                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16796            app.adjType = "exec-service";
16797            procState = ActivityManager.PROCESS_STATE_SERVICE;
16798            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16799        } else {
16800            // As far as we know the process is empty.  We may change our mind later.
16801            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16802            // At this point we don't actually know the adjustment.  Use the cached adj
16803            // value that the caller wants us to.
16804            adj = cachedAdj;
16805            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16806            app.cached = true;
16807            app.empty = true;
16808            app.adjType = "cch-empty";
16809        }
16810
16811        // Examine all activities if not already foreground.
16812        if (!foregroundActivities && activitiesSize > 0) {
16813            for (int j = 0; j < activitiesSize; j++) {
16814                final ActivityRecord r = app.activities.get(j);
16815                if (r.app != app) {
16816                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16817                            + app + "?!?");
16818                    continue;
16819                }
16820                if (r.visible) {
16821                    // App has a visible activity; only upgrade adjustment.
16822                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16823                        adj = ProcessList.VISIBLE_APP_ADJ;
16824                        app.adjType = "visible";
16825                    }
16826                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16827                        procState = ActivityManager.PROCESS_STATE_TOP;
16828                    }
16829                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16830                    app.cached = false;
16831                    app.empty = false;
16832                    foregroundActivities = true;
16833                    break;
16834                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16835                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16836                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16837                        app.adjType = "pausing";
16838                    }
16839                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16840                        procState = ActivityManager.PROCESS_STATE_TOP;
16841                    }
16842                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16843                    app.cached = false;
16844                    app.empty = false;
16845                    foregroundActivities = true;
16846                } else if (r.state == ActivityState.STOPPING) {
16847                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16848                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16849                        app.adjType = "stopping";
16850                    }
16851                    // For the process state, we will at this point consider the
16852                    // process to be cached.  It will be cached either as an activity
16853                    // or empty depending on whether the activity is finishing.  We do
16854                    // this so that we can treat the process as cached for purposes of
16855                    // memory trimming (determing current memory level, trim command to
16856                    // send to process) since there can be an arbitrary number of stopping
16857                    // processes and they should soon all go into the cached state.
16858                    if (!r.finishing) {
16859                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16860                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16861                        }
16862                    }
16863                    app.cached = false;
16864                    app.empty = false;
16865                    foregroundActivities = true;
16866                } else {
16867                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16868                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16869                        app.adjType = "cch-act";
16870                    }
16871                }
16872            }
16873        }
16874
16875        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16876            if (app.foregroundServices) {
16877                // The user is aware of this app, so make it visible.
16878                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16879                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16880                app.cached = false;
16881                app.adjType = "fg-service";
16882                schedGroup = Process.THREAD_GROUP_DEFAULT;
16883            } else if (app.forcingToForeground != null) {
16884                // The user is aware of this app, so make it visible.
16885                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16886                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16887                app.cached = false;
16888                app.adjType = "force-fg";
16889                app.adjSource = app.forcingToForeground;
16890                schedGroup = Process.THREAD_GROUP_DEFAULT;
16891            }
16892        }
16893
16894        if (app == mHeavyWeightProcess) {
16895            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16896                // We don't want to kill the current heavy-weight process.
16897                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16898                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16899                app.cached = false;
16900                app.adjType = "heavy";
16901            }
16902            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16903                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16904            }
16905        }
16906
16907        if (app == mHomeProcess) {
16908            if (adj > ProcessList.HOME_APP_ADJ) {
16909                // This process is hosting what we currently consider to be the
16910                // home app, so we don't want to let it go into the background.
16911                adj = ProcessList.HOME_APP_ADJ;
16912                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16913                app.cached = false;
16914                app.adjType = "home";
16915            }
16916            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16917                procState = ActivityManager.PROCESS_STATE_HOME;
16918            }
16919        }
16920
16921        if (app == mPreviousProcess && app.activities.size() > 0) {
16922            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16923                // This was the previous process that showed UI to the user.
16924                // We want to try to keep it around more aggressively, to give
16925                // a good experience around switching between two apps.
16926                adj = ProcessList.PREVIOUS_APP_ADJ;
16927                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16928                app.cached = false;
16929                app.adjType = "previous";
16930            }
16931            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16932                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16933            }
16934        }
16935
16936        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16937                + " reason=" + app.adjType);
16938
16939        // By default, we use the computed adjustment.  It may be changed if
16940        // there are applications dependent on our services or providers, but
16941        // this gives us a baseline and makes sure we don't get into an
16942        // infinite recursion.
16943        app.adjSeq = mAdjSeq;
16944        app.curRawAdj = adj;
16945        app.hasStartedServices = false;
16946
16947        if (mBackupTarget != null && app == mBackupTarget.app) {
16948            // If possible we want to avoid killing apps while they're being backed up
16949            if (adj > ProcessList.BACKUP_APP_ADJ) {
16950                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
16951                adj = ProcessList.BACKUP_APP_ADJ;
16952                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16953                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16954                }
16955                app.adjType = "backup";
16956                app.cached = false;
16957            }
16958            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16959                procState = ActivityManager.PROCESS_STATE_BACKUP;
16960            }
16961        }
16962
16963        boolean mayBeTop = false;
16964
16965        for (int is = app.services.size()-1;
16966                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16967                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16968                        || procState > ActivityManager.PROCESS_STATE_TOP);
16969                is--) {
16970            ServiceRecord s = app.services.valueAt(is);
16971            if (s.startRequested) {
16972                app.hasStartedServices = true;
16973                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16974                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16975                }
16976                if (app.hasShownUi && app != mHomeProcess) {
16977                    // If this process has shown some UI, let it immediately
16978                    // go to the LRU list because it may be pretty heavy with
16979                    // UI stuff.  We'll tag it with a label just to help
16980                    // debug and understand what is going on.
16981                    if (adj > ProcessList.SERVICE_ADJ) {
16982                        app.adjType = "cch-started-ui-services";
16983                    }
16984                } else {
16985                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16986                        // This service has seen some activity within
16987                        // recent memory, so we will keep its process ahead
16988                        // of the background processes.
16989                        if (adj > ProcessList.SERVICE_ADJ) {
16990                            adj = ProcessList.SERVICE_ADJ;
16991                            app.adjType = "started-services";
16992                            app.cached = false;
16993                        }
16994                    }
16995                    // If we have let the service slide into the background
16996                    // state, still have some text describing what it is doing
16997                    // even though the service no longer has an impact.
16998                    if (adj > ProcessList.SERVICE_ADJ) {
16999                        app.adjType = "cch-started-services";
17000                    }
17001                }
17002            }
17003            for (int conni = s.connections.size()-1;
17004                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17005                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17006                            || procState > ActivityManager.PROCESS_STATE_TOP);
17007                    conni--) {
17008                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17009                for (int i = 0;
17010                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17011                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17012                                || procState > ActivityManager.PROCESS_STATE_TOP);
17013                        i++) {
17014                    // XXX should compute this based on the max of
17015                    // all connected clients.
17016                    ConnectionRecord cr = clist.get(i);
17017                    if (cr.binding.client == app) {
17018                        // Binding to ourself is not interesting.
17019                        continue;
17020                    }
17021                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17022                        ProcessRecord client = cr.binding.client;
17023                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17024                                TOP_APP, doingAll, now);
17025                        int clientProcState = client.curProcState;
17026                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17027                            // If the other app is cached for any reason, for purposes here
17028                            // we are going to consider it empty.  The specific cached state
17029                            // doesn't propagate except under certain conditions.
17030                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17031                        }
17032                        String adjType = null;
17033                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17034                            // Not doing bind OOM management, so treat
17035                            // this guy more like a started service.
17036                            if (app.hasShownUi && app != mHomeProcess) {
17037                                // If this process has shown some UI, let it immediately
17038                                // go to the LRU list because it may be pretty heavy with
17039                                // UI stuff.  We'll tag it with a label just to help
17040                                // debug and understand what is going on.
17041                                if (adj > clientAdj) {
17042                                    adjType = "cch-bound-ui-services";
17043                                }
17044                                app.cached = false;
17045                                clientAdj = adj;
17046                                clientProcState = procState;
17047                            } else {
17048                                if (now >= (s.lastActivity
17049                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17050                                    // This service has not seen activity within
17051                                    // recent memory, so allow it to drop to the
17052                                    // LRU list if there is no other reason to keep
17053                                    // it around.  We'll also tag it with a label just
17054                                    // to help debug and undertand what is going on.
17055                                    if (adj > clientAdj) {
17056                                        adjType = "cch-bound-services";
17057                                    }
17058                                    clientAdj = adj;
17059                                }
17060                            }
17061                        }
17062                        if (adj > clientAdj) {
17063                            // If this process has recently shown UI, and
17064                            // the process that is binding to it is less
17065                            // important than being visible, then we don't
17066                            // care about the binding as much as we care
17067                            // about letting this process get into the LRU
17068                            // list to be killed and restarted if needed for
17069                            // memory.
17070                            if (app.hasShownUi && app != mHomeProcess
17071                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17072                                adjType = "cch-bound-ui-services";
17073                            } else {
17074                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17075                                        |Context.BIND_IMPORTANT)) != 0) {
17076                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17077                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17078                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17079                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17080                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17081                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17082                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17083                                    adj = clientAdj;
17084                                } else {
17085                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17086                                        adj = ProcessList.VISIBLE_APP_ADJ;
17087                                    }
17088                                }
17089                                if (!client.cached) {
17090                                    app.cached = false;
17091                                }
17092                                adjType = "service";
17093                            }
17094                        }
17095                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17096                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17097                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17098                            }
17099                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17100                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17101                                    // Special handling of clients who are in the top state.
17102                                    // We *may* want to consider this process to be in the
17103                                    // top state as well, but only if there is not another
17104                                    // reason for it to be running.  Being on the top is a
17105                                    // special state, meaning you are specifically running
17106                                    // for the current top app.  If the process is already
17107                                    // running in the background for some other reason, it
17108                                    // is more important to continue considering it to be
17109                                    // in the background state.
17110                                    mayBeTop = true;
17111                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17112                                } else {
17113                                    // Special handling for above-top states (persistent
17114                                    // processes).  These should not bring the current process
17115                                    // into the top state, since they are not on top.  Instead
17116                                    // give them the best state after that.
17117                                    clientProcState =
17118                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17119                                }
17120                            }
17121                        } else {
17122                            if (clientProcState <
17123                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17124                                clientProcState =
17125                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17126                            }
17127                        }
17128                        if (procState > clientProcState) {
17129                            procState = clientProcState;
17130                        }
17131                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17132                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17133                            app.pendingUiClean = true;
17134                        }
17135                        if (adjType != null) {
17136                            app.adjType = adjType;
17137                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17138                                    .REASON_SERVICE_IN_USE;
17139                            app.adjSource = cr.binding.client;
17140                            app.adjSourceProcState = clientProcState;
17141                            app.adjTarget = s.name;
17142                        }
17143                    }
17144                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17145                        app.treatLikeActivity = true;
17146                    }
17147                    final ActivityRecord a = cr.activity;
17148                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17149                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17150                                (a.visible || a.state == ActivityState.RESUMED
17151                                 || a.state == ActivityState.PAUSING)) {
17152                            adj = ProcessList.FOREGROUND_APP_ADJ;
17153                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17154                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17155                            }
17156                            app.cached = false;
17157                            app.adjType = "service";
17158                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17159                                    .REASON_SERVICE_IN_USE;
17160                            app.adjSource = a;
17161                            app.adjSourceProcState = procState;
17162                            app.adjTarget = s.name;
17163                        }
17164                    }
17165                }
17166            }
17167        }
17168
17169        for (int provi = app.pubProviders.size()-1;
17170                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17171                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17172                        || procState > ActivityManager.PROCESS_STATE_TOP);
17173                provi--) {
17174            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17175            for (int i = cpr.connections.size()-1;
17176                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17177                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17178                            || procState > ActivityManager.PROCESS_STATE_TOP);
17179                    i--) {
17180                ContentProviderConnection conn = cpr.connections.get(i);
17181                ProcessRecord client = conn.client;
17182                if (client == app) {
17183                    // Being our own client is not interesting.
17184                    continue;
17185                }
17186                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17187                int clientProcState = client.curProcState;
17188                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17189                    // If the other app is cached for any reason, for purposes here
17190                    // we are going to consider it empty.
17191                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17192                }
17193                if (adj > clientAdj) {
17194                    if (app.hasShownUi && app != mHomeProcess
17195                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17196                        app.adjType = "cch-ui-provider";
17197                    } else {
17198                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17199                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17200                        app.adjType = "provider";
17201                    }
17202                    app.cached &= client.cached;
17203                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17204                            .REASON_PROVIDER_IN_USE;
17205                    app.adjSource = client;
17206                    app.adjSourceProcState = clientProcState;
17207                    app.adjTarget = cpr.name;
17208                }
17209                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17210                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17211                        // Special handling of clients who are in the top state.
17212                        // We *may* want to consider this process to be in the
17213                        // top state as well, but only if there is not another
17214                        // reason for it to be running.  Being on the top is a
17215                        // special state, meaning you are specifically running
17216                        // for the current top app.  If the process is already
17217                        // running in the background for some other reason, it
17218                        // is more important to continue considering it to be
17219                        // in the background state.
17220                        mayBeTop = true;
17221                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17222                    } else {
17223                        // Special handling for above-top states (persistent
17224                        // processes).  These should not bring the current process
17225                        // into the top state, since they are not on top.  Instead
17226                        // give them the best state after that.
17227                        clientProcState =
17228                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17229                    }
17230                }
17231                if (procState > clientProcState) {
17232                    procState = clientProcState;
17233                }
17234                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17235                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17236                }
17237            }
17238            // If the provider has external (non-framework) process
17239            // dependencies, ensure that its adjustment is at least
17240            // FOREGROUND_APP_ADJ.
17241            if (cpr.hasExternalProcessHandles()) {
17242                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17243                    adj = ProcessList.FOREGROUND_APP_ADJ;
17244                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17245                    app.cached = false;
17246                    app.adjType = "provider";
17247                    app.adjTarget = cpr.name;
17248                }
17249                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17250                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17251                }
17252            }
17253        }
17254
17255        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17256            // A client of one of our services or providers is in the top state.  We
17257            // *may* want to be in the top state, but not if we are already running in
17258            // the background for some other reason.  For the decision here, we are going
17259            // to pick out a few specific states that we want to remain in when a client
17260            // is top (states that tend to be longer-term) and otherwise allow it to go
17261            // to the top state.
17262            switch (procState) {
17263                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17264                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17265                case ActivityManager.PROCESS_STATE_SERVICE:
17266                    // These all are longer-term states, so pull them up to the top
17267                    // of the background states, but not all the way to the top state.
17268                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17269                    break;
17270                default:
17271                    // Otherwise, top is a better choice, so take it.
17272                    procState = ActivityManager.PROCESS_STATE_TOP;
17273                    break;
17274            }
17275        }
17276
17277        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17278            if (app.hasClientActivities) {
17279                // This is a cached process, but with client activities.  Mark it so.
17280                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17281                app.adjType = "cch-client-act";
17282            } else if (app.treatLikeActivity) {
17283                // This is a cached process, but somebody wants us to treat it like it has
17284                // an activity, okay!
17285                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17286                app.adjType = "cch-as-act";
17287            }
17288        }
17289
17290        if (adj == ProcessList.SERVICE_ADJ) {
17291            if (doingAll) {
17292                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17293                mNewNumServiceProcs++;
17294                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17295                if (!app.serviceb) {
17296                    // This service isn't far enough down on the LRU list to
17297                    // normally be a B service, but if we are low on RAM and it
17298                    // is large we want to force it down since we would prefer to
17299                    // keep launcher over it.
17300                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17301                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17302                        app.serviceHighRam = true;
17303                        app.serviceb = true;
17304                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17305                    } else {
17306                        mNewNumAServiceProcs++;
17307                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17308                    }
17309                } else {
17310                    app.serviceHighRam = false;
17311                }
17312            }
17313            if (app.serviceb) {
17314                adj = ProcessList.SERVICE_B_ADJ;
17315            }
17316        }
17317
17318        app.curRawAdj = adj;
17319
17320        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17321        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17322        if (adj > app.maxAdj) {
17323            adj = app.maxAdj;
17324            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17325                schedGroup = Process.THREAD_GROUP_DEFAULT;
17326            }
17327        }
17328
17329        // Do final modification to adj.  Everything we do between here and applying
17330        // the final setAdj must be done in this function, because we will also use
17331        // it when computing the final cached adj later.  Note that we don't need to
17332        // worry about this for max adj above, since max adj will always be used to
17333        // keep it out of the cached vaues.
17334        app.curAdj = app.modifyRawOomAdj(adj);
17335        app.curSchedGroup = schedGroup;
17336        app.curProcState = procState;
17337        app.foregroundActivities = foregroundActivities;
17338
17339        return app.curRawAdj;
17340    }
17341
17342    /**
17343     * Record new PSS sample for a process.
17344     */
17345    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
17346        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss*1024, uss*1024);
17347        proc.lastPssTime = now;
17348        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17349        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17350                + ": " + pss + " lastPss=" + proc.lastPss
17351                + " state=" + ProcessList.makeProcStateString(procState));
17352        if (proc.initialIdlePss == 0) {
17353            proc.initialIdlePss = pss;
17354        }
17355        proc.lastPss = pss;
17356        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17357            proc.lastCachedPss = pss;
17358        }
17359
17360        Long check = mMemWatchProcesses.get(proc.processName);
17361        if (check != null) {
17362            if ((pss*1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
17363                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17364                if (!isDebuggable) {
17365                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
17366                        isDebuggable = true;
17367                    }
17368                }
17369                if (isDebuggable) {
17370                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
17371                    final ProcessRecord myProc = proc;
17372                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
17373                    mMemWatchDumpProcName = proc.processName;
17374                    mMemWatchDumpFile = heapdumpFile.toString();
17375                    mMemWatchDumpPid = proc.pid;
17376                    mMemWatchDumpUid = proc.uid;
17377                    BackgroundThread.getHandler().post(new Runnable() {
17378                        @Override
17379                        public void run() {
17380                            revokeUriPermission(ActivityThread.currentActivityThread()
17381                                            .getApplicationThread(),
17382                                    DumpHeapActivity.JAVA_URI,
17383                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
17384                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
17385                                    UserHandle.myUserId());
17386                            ParcelFileDescriptor fd = null;
17387                            try {
17388                                heapdumpFile.delete();
17389                                fd = ParcelFileDescriptor.open(heapdumpFile,
17390                                        ParcelFileDescriptor.MODE_CREATE |
17391                                                ParcelFileDescriptor.MODE_TRUNCATE |
17392                                                ParcelFileDescriptor.MODE_READ_WRITE);
17393                                IApplicationThread thread = myProc.thread;
17394                                if (thread != null) {
17395                                    try {
17396                                        if (DEBUG_PSS) Slog.d(TAG, "Requesting dump heap from "
17397                                                + myProc + " to " + heapdumpFile);
17398                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
17399                                    } catch (RemoteException e) {
17400                                    }
17401                                }
17402                            } catch (FileNotFoundException e) {
17403                                e.printStackTrace();
17404                            } finally {
17405                                if (fd != null) {
17406                                    try {
17407                                        fd.close();
17408                                    } catch (IOException e) {
17409                                    }
17410                                }
17411                            }
17412                        }
17413                    });
17414                } else {
17415                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
17416                            + ", but debugging not enabled");
17417                }
17418            }
17419        }
17420    }
17421
17422    /**
17423     * Schedule PSS collection of a process.
17424     */
17425    void requestPssLocked(ProcessRecord proc, int procState) {
17426        if (mPendingPssProcesses.contains(proc)) {
17427            return;
17428        }
17429        if (mPendingPssProcesses.size() == 0) {
17430            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17431        }
17432        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17433        proc.pssProcState = procState;
17434        mPendingPssProcesses.add(proc);
17435    }
17436
17437    /**
17438     * Schedule PSS collection of all processes.
17439     */
17440    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17441        if (!always) {
17442            if (now < (mLastFullPssTime +
17443                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17444                return;
17445            }
17446        }
17447        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17448        mLastFullPssTime = now;
17449        mFullPssPending = true;
17450        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17451        mPendingPssProcesses.clear();
17452        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17453            ProcessRecord app = mLruProcesses.get(i);
17454            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17455                app.pssProcState = app.setProcState;
17456                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17457                        mTestPssMode, isSleeping(), now);
17458                mPendingPssProcesses.add(app);
17459            }
17460        }
17461        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17462    }
17463
17464    public void setTestPssMode(boolean enabled) {
17465        synchronized (this) {
17466            mTestPssMode = enabled;
17467            if (enabled) {
17468                // Whenever we enable the mode, we want to take a snapshot all of current
17469                // process mem use.
17470                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17471            }
17472        }
17473    }
17474
17475    /**
17476     * Ask a given process to GC right now.
17477     */
17478    final void performAppGcLocked(ProcessRecord app) {
17479        try {
17480            app.lastRequestedGc = SystemClock.uptimeMillis();
17481            if (app.thread != null) {
17482                if (app.reportLowMemory) {
17483                    app.reportLowMemory = false;
17484                    app.thread.scheduleLowMemory();
17485                } else {
17486                    app.thread.processInBackground();
17487                }
17488            }
17489        } catch (Exception e) {
17490            // whatever.
17491        }
17492    }
17493
17494    /**
17495     * Returns true if things are idle enough to perform GCs.
17496     */
17497    private final boolean canGcNowLocked() {
17498        boolean processingBroadcasts = false;
17499        for (BroadcastQueue q : mBroadcastQueues) {
17500            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17501                processingBroadcasts = true;
17502            }
17503        }
17504        return !processingBroadcasts
17505                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17506    }
17507
17508    /**
17509     * Perform GCs on all processes that are waiting for it, but only
17510     * if things are idle.
17511     */
17512    final void performAppGcsLocked() {
17513        final int N = mProcessesToGc.size();
17514        if (N <= 0) {
17515            return;
17516        }
17517        if (canGcNowLocked()) {
17518            while (mProcessesToGc.size() > 0) {
17519                ProcessRecord proc = mProcessesToGc.remove(0);
17520                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17521                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17522                            <= SystemClock.uptimeMillis()) {
17523                        // To avoid spamming the system, we will GC processes one
17524                        // at a time, waiting a few seconds between each.
17525                        performAppGcLocked(proc);
17526                        scheduleAppGcsLocked();
17527                        return;
17528                    } else {
17529                        // It hasn't been long enough since we last GCed this
17530                        // process...  put it in the list to wait for its time.
17531                        addProcessToGcListLocked(proc);
17532                        break;
17533                    }
17534                }
17535            }
17536
17537            scheduleAppGcsLocked();
17538        }
17539    }
17540
17541    /**
17542     * If all looks good, perform GCs on all processes waiting for them.
17543     */
17544    final void performAppGcsIfAppropriateLocked() {
17545        if (canGcNowLocked()) {
17546            performAppGcsLocked();
17547            return;
17548        }
17549        // Still not idle, wait some more.
17550        scheduleAppGcsLocked();
17551    }
17552
17553    /**
17554     * Schedule the execution of all pending app GCs.
17555     */
17556    final void scheduleAppGcsLocked() {
17557        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17558
17559        if (mProcessesToGc.size() > 0) {
17560            // Schedule a GC for the time to the next process.
17561            ProcessRecord proc = mProcessesToGc.get(0);
17562            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17563
17564            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17565            long now = SystemClock.uptimeMillis();
17566            if (when < (now+GC_TIMEOUT)) {
17567                when = now + GC_TIMEOUT;
17568            }
17569            mHandler.sendMessageAtTime(msg, when);
17570        }
17571    }
17572
17573    /**
17574     * Add a process to the array of processes waiting to be GCed.  Keeps the
17575     * list in sorted order by the last GC time.  The process can't already be
17576     * on the list.
17577     */
17578    final void addProcessToGcListLocked(ProcessRecord proc) {
17579        boolean added = false;
17580        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17581            if (mProcessesToGc.get(i).lastRequestedGc <
17582                    proc.lastRequestedGc) {
17583                added = true;
17584                mProcessesToGc.add(i+1, proc);
17585                break;
17586            }
17587        }
17588        if (!added) {
17589            mProcessesToGc.add(0, proc);
17590        }
17591    }
17592
17593    /**
17594     * Set up to ask a process to GC itself.  This will either do it
17595     * immediately, or put it on the list of processes to gc the next
17596     * time things are idle.
17597     */
17598    final void scheduleAppGcLocked(ProcessRecord app) {
17599        long now = SystemClock.uptimeMillis();
17600        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17601            return;
17602        }
17603        if (!mProcessesToGc.contains(app)) {
17604            addProcessToGcListLocked(app);
17605            scheduleAppGcsLocked();
17606        }
17607    }
17608
17609    final void checkExcessivePowerUsageLocked(boolean doKills) {
17610        updateCpuStatsNow();
17611
17612        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17613        boolean doWakeKills = doKills;
17614        boolean doCpuKills = doKills;
17615        if (mLastPowerCheckRealtime == 0) {
17616            doWakeKills = false;
17617        }
17618        if (mLastPowerCheckUptime == 0) {
17619            doCpuKills = false;
17620        }
17621        if (stats.isScreenOn()) {
17622            doWakeKills = false;
17623        }
17624        final long curRealtime = SystemClock.elapsedRealtime();
17625        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17626        final long curUptime = SystemClock.uptimeMillis();
17627        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17628        mLastPowerCheckRealtime = curRealtime;
17629        mLastPowerCheckUptime = curUptime;
17630        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17631            doWakeKills = false;
17632        }
17633        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17634            doCpuKills = false;
17635        }
17636        int i = mLruProcesses.size();
17637        while (i > 0) {
17638            i--;
17639            ProcessRecord app = mLruProcesses.get(i);
17640            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17641                long wtime;
17642                synchronized (stats) {
17643                    wtime = stats.getProcessWakeTime(app.info.uid,
17644                            app.pid, curRealtime);
17645                }
17646                long wtimeUsed = wtime - app.lastWakeTime;
17647                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17648                if (DEBUG_POWER) {
17649                    StringBuilder sb = new StringBuilder(128);
17650                    sb.append("Wake for ");
17651                    app.toShortString(sb);
17652                    sb.append(": over ");
17653                    TimeUtils.formatDuration(realtimeSince, sb);
17654                    sb.append(" used ");
17655                    TimeUtils.formatDuration(wtimeUsed, sb);
17656                    sb.append(" (");
17657                    sb.append((wtimeUsed*100)/realtimeSince);
17658                    sb.append("%)");
17659                    Slog.i(TAG, sb.toString());
17660                    sb.setLength(0);
17661                    sb.append("CPU for ");
17662                    app.toShortString(sb);
17663                    sb.append(": over ");
17664                    TimeUtils.formatDuration(uptimeSince, sb);
17665                    sb.append(" used ");
17666                    TimeUtils.formatDuration(cputimeUsed, sb);
17667                    sb.append(" (");
17668                    sb.append((cputimeUsed*100)/uptimeSince);
17669                    sb.append("%)");
17670                    Slog.i(TAG, sb.toString());
17671                }
17672                // If a process has held a wake lock for more
17673                // than 50% of the time during this period,
17674                // that sounds bad.  Kill!
17675                if (doWakeKills && realtimeSince > 0
17676                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17677                    synchronized (stats) {
17678                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17679                                realtimeSince, wtimeUsed);
17680                    }
17681                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17682                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17683                } else if (doCpuKills && uptimeSince > 0
17684                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17685                    synchronized (stats) {
17686                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17687                                uptimeSince, cputimeUsed);
17688                    }
17689                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17690                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17691                } else {
17692                    app.lastWakeTime = wtime;
17693                    app.lastCpuTime = app.curCpuTime;
17694                }
17695            }
17696        }
17697    }
17698
17699    private final boolean applyOomAdjLocked(ProcessRecord app,
17700            ProcessRecord TOP_APP, boolean doingAll, long now) {
17701        boolean success = true;
17702
17703        if (app.curRawAdj != app.setRawAdj) {
17704            app.setRawAdj = app.curRawAdj;
17705        }
17706
17707        int changes = 0;
17708
17709        if (app.curAdj != app.setAdj) {
17710            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17711            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17712                TAG, "Set " + app.pid + " " + app.processName +
17713                " adj " + app.curAdj + ": " + app.adjType);
17714            app.setAdj = app.curAdj;
17715        }
17716
17717        if (app.setSchedGroup != app.curSchedGroup) {
17718            app.setSchedGroup = app.curSchedGroup;
17719            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17720                    "Setting process group of " + app.processName
17721                    + " to " + app.curSchedGroup);
17722            if (app.waitingToKill != null &&
17723                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17724                app.kill(app.waitingToKill, true);
17725                success = false;
17726            } else {
17727                if (true) {
17728                    long oldId = Binder.clearCallingIdentity();
17729                    try {
17730                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17731                    } catch (Exception e) {
17732                        Slog.w(TAG, "Failed setting process group of " + app.pid
17733                                + " to " + app.curSchedGroup);
17734                        e.printStackTrace();
17735                    } finally {
17736                        Binder.restoreCallingIdentity(oldId);
17737                    }
17738                } else {
17739                    if (app.thread != null) {
17740                        try {
17741                            app.thread.setSchedulingGroup(app.curSchedGroup);
17742                        } catch (RemoteException e) {
17743                        }
17744                    }
17745                }
17746                Process.setSwappiness(app.pid,
17747                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17748            }
17749        }
17750        if (app.repForegroundActivities != app.foregroundActivities) {
17751            app.repForegroundActivities = app.foregroundActivities;
17752            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17753        }
17754        if (app.repProcState != app.curProcState) {
17755            app.repProcState = app.curProcState;
17756            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17757            if (app.thread != null) {
17758                try {
17759                    if (false) {
17760                        //RuntimeException h = new RuntimeException("here");
17761                        Slog.i(TAG, "Sending new process state " + app.repProcState
17762                                + " to " + app /*, h*/);
17763                    }
17764                    app.thread.setProcessState(app.repProcState);
17765                } catch (RemoteException e) {
17766                }
17767            }
17768        }
17769        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17770                app.setProcState)) {
17771            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17772                // Experimental code to more aggressively collect pss while
17773                // running test...  the problem is that this tends to collect
17774                // the data right when a process is transitioning between process
17775                // states, which well tend to give noisy data.
17776                long start = SystemClock.uptimeMillis();
17777                long pss = Debug.getPss(app.pid, mTmpLong, null);
17778                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
17779                mPendingPssProcesses.remove(app);
17780                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17781                        + " to " + app.curProcState + ": "
17782                        + (SystemClock.uptimeMillis()-start) + "ms");
17783            }
17784            app.lastStateTime = now;
17785            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17786                    mTestPssMode, isSleeping(), now);
17787            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17788                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17789                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17790                    + (app.nextPssTime-now) + ": " + app);
17791        } else {
17792            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17793                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
17794                    mTestPssMode)))) {
17795                requestPssLocked(app, app.setProcState);
17796                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17797                        mTestPssMode, isSleeping(), now);
17798            } else if (false && DEBUG_PSS) {
17799                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17800            }
17801        }
17802        if (app.setProcState != app.curProcState) {
17803            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17804                    "Proc state change of " + app.processName
17805                    + " to " + app.curProcState);
17806            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17807            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17808            if (setImportant && !curImportant) {
17809                // This app is no longer something we consider important enough to allow to
17810                // use arbitrary amounts of battery power.  Note
17811                // its current wake lock time to later know to kill it if
17812                // it is not behaving well.
17813                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17814                synchronized (stats) {
17815                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17816                            app.pid, SystemClock.elapsedRealtime());
17817                }
17818                app.lastCpuTime = app.curCpuTime;
17819
17820            }
17821            app.setProcState = app.curProcState;
17822            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17823                app.notCachedSinceIdle = false;
17824            }
17825            if (!doingAll) {
17826                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17827            } else {
17828                app.procStateChanged = true;
17829            }
17830        }
17831
17832        if (changes != 0) {
17833            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17834            int i = mPendingProcessChanges.size()-1;
17835            ProcessChangeItem item = null;
17836            while (i >= 0) {
17837                item = mPendingProcessChanges.get(i);
17838                if (item.pid == app.pid) {
17839                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17840                    break;
17841                }
17842                i--;
17843            }
17844            if (i < 0) {
17845                // No existing item in pending changes; need a new one.
17846                final int NA = mAvailProcessChanges.size();
17847                if (NA > 0) {
17848                    item = mAvailProcessChanges.remove(NA-1);
17849                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17850                } else {
17851                    item = new ProcessChangeItem();
17852                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17853                }
17854                item.changes = 0;
17855                item.pid = app.pid;
17856                item.uid = app.info.uid;
17857                if (mPendingProcessChanges.size() == 0) {
17858                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17859                            "*** Enqueueing dispatch processes changed!");
17860                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17861                }
17862                mPendingProcessChanges.add(item);
17863            }
17864            item.changes |= changes;
17865            item.processState = app.repProcState;
17866            item.foregroundActivities = app.repForegroundActivities;
17867            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17868                    + Integer.toHexString(System.identityHashCode(item))
17869                    + " " + app.toShortString() + ": changes=" + item.changes
17870                    + " procState=" + item.processState
17871                    + " foreground=" + item.foregroundActivities
17872                    + " type=" + app.adjType + " source=" + app.adjSource
17873                    + " target=" + app.adjTarget);
17874        }
17875
17876        return success;
17877    }
17878
17879    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17880        if (proc.thread != null) {
17881            if (proc.baseProcessTracker != null) {
17882                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17883            }
17884            if (proc.repProcState >= 0) {
17885                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17886                        proc.repProcState);
17887            }
17888        }
17889    }
17890
17891    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17892            ProcessRecord TOP_APP, boolean doingAll, long now) {
17893        if (app.thread == null) {
17894            return false;
17895        }
17896
17897        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17898
17899        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17900    }
17901
17902    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17903            boolean oomAdj) {
17904        if (isForeground != proc.foregroundServices) {
17905            proc.foregroundServices = isForeground;
17906            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17907                    proc.info.uid);
17908            if (isForeground) {
17909                if (curProcs == null) {
17910                    curProcs = new ArrayList<ProcessRecord>();
17911                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17912                }
17913                if (!curProcs.contains(proc)) {
17914                    curProcs.add(proc);
17915                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17916                            proc.info.packageName, proc.info.uid);
17917                }
17918            } else {
17919                if (curProcs != null) {
17920                    if (curProcs.remove(proc)) {
17921                        mBatteryStatsService.noteEvent(
17922                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17923                                proc.info.packageName, proc.info.uid);
17924                        if (curProcs.size() <= 0) {
17925                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17926                        }
17927                    }
17928                }
17929            }
17930            if (oomAdj) {
17931                updateOomAdjLocked();
17932            }
17933        }
17934    }
17935
17936    private final ActivityRecord resumedAppLocked() {
17937        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17938        String pkg;
17939        int uid;
17940        if (act != null) {
17941            pkg = act.packageName;
17942            uid = act.info.applicationInfo.uid;
17943        } else {
17944            pkg = null;
17945            uid = -1;
17946        }
17947        // Has the UID or resumed package name changed?
17948        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17949                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17950            if (mCurResumedPackage != null) {
17951                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17952                        mCurResumedPackage, mCurResumedUid);
17953            }
17954            mCurResumedPackage = pkg;
17955            mCurResumedUid = uid;
17956            if (mCurResumedPackage != null) {
17957                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17958                        mCurResumedPackage, mCurResumedUid);
17959            }
17960        }
17961        return act;
17962    }
17963
17964    final boolean updateOomAdjLocked(ProcessRecord app) {
17965        final ActivityRecord TOP_ACT = resumedAppLocked();
17966        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17967        final boolean wasCached = app.cached;
17968
17969        mAdjSeq++;
17970
17971        // This is the desired cached adjusment we want to tell it to use.
17972        // If our app is currently cached, we know it, and that is it.  Otherwise,
17973        // we don't know it yet, and it needs to now be cached we will then
17974        // need to do a complete oom adj.
17975        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17976                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17977        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17978                SystemClock.uptimeMillis());
17979        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17980            // Changed to/from cached state, so apps after it in the LRU
17981            // list may also be changed.
17982            updateOomAdjLocked();
17983        }
17984        return success;
17985    }
17986
17987    final void updateOomAdjLocked() {
17988        final ActivityRecord TOP_ACT = resumedAppLocked();
17989        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17990        final long now = SystemClock.uptimeMillis();
17991        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17992        final int N = mLruProcesses.size();
17993
17994        if (false) {
17995            RuntimeException e = new RuntimeException();
17996            e.fillInStackTrace();
17997            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17998        }
17999
18000        mAdjSeq++;
18001        mNewNumServiceProcs = 0;
18002        mNewNumAServiceProcs = 0;
18003
18004        final int emptyProcessLimit;
18005        final int cachedProcessLimit;
18006        if (mProcessLimit <= 0) {
18007            emptyProcessLimit = cachedProcessLimit = 0;
18008        } else if (mProcessLimit == 1) {
18009            emptyProcessLimit = 1;
18010            cachedProcessLimit = 0;
18011        } else {
18012            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18013            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18014        }
18015
18016        // Let's determine how many processes we have running vs.
18017        // how many slots we have for background processes; we may want
18018        // to put multiple processes in a slot of there are enough of
18019        // them.
18020        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18021                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18022        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18023        if (numEmptyProcs > cachedProcessLimit) {
18024            // If there are more empty processes than our limit on cached
18025            // processes, then use the cached process limit for the factor.
18026            // This ensures that the really old empty processes get pushed
18027            // down to the bottom, so if we are running low on memory we will
18028            // have a better chance at keeping around more cached processes
18029            // instead of a gazillion empty processes.
18030            numEmptyProcs = cachedProcessLimit;
18031        }
18032        int emptyFactor = numEmptyProcs/numSlots;
18033        if (emptyFactor < 1) emptyFactor = 1;
18034        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18035        if (cachedFactor < 1) cachedFactor = 1;
18036        int stepCached = 0;
18037        int stepEmpty = 0;
18038        int numCached = 0;
18039        int numEmpty = 0;
18040        int numTrimming = 0;
18041
18042        mNumNonCachedProcs = 0;
18043        mNumCachedHiddenProcs = 0;
18044
18045        // First update the OOM adjustment for each of the
18046        // application processes based on their current state.
18047        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18048        int nextCachedAdj = curCachedAdj+1;
18049        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18050        int nextEmptyAdj = curEmptyAdj+2;
18051        for (int i=N-1; i>=0; i--) {
18052            ProcessRecord app = mLruProcesses.get(i);
18053            if (!app.killedByAm && app.thread != null) {
18054                app.procStateChanged = false;
18055                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18056
18057                // If we haven't yet assigned the final cached adj
18058                // to the process, do that now.
18059                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18060                    switch (app.curProcState) {
18061                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18062                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18063                            // This process is a cached process holding activities...
18064                            // assign it the next cached value for that type, and then
18065                            // step that cached level.
18066                            app.curRawAdj = curCachedAdj;
18067                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18068                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18069                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18070                                    + ")");
18071                            if (curCachedAdj != nextCachedAdj) {
18072                                stepCached++;
18073                                if (stepCached >= cachedFactor) {
18074                                    stepCached = 0;
18075                                    curCachedAdj = nextCachedAdj;
18076                                    nextCachedAdj += 2;
18077                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18078                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18079                                    }
18080                                }
18081                            }
18082                            break;
18083                        default:
18084                            // For everything else, assign next empty cached process
18085                            // level and bump that up.  Note that this means that
18086                            // long-running services that have dropped down to the
18087                            // cached level will be treated as empty (since their process
18088                            // state is still as a service), which is what we want.
18089                            app.curRawAdj = curEmptyAdj;
18090                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18091                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18092                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18093                                    + ")");
18094                            if (curEmptyAdj != nextEmptyAdj) {
18095                                stepEmpty++;
18096                                if (stepEmpty >= emptyFactor) {
18097                                    stepEmpty = 0;
18098                                    curEmptyAdj = nextEmptyAdj;
18099                                    nextEmptyAdj += 2;
18100                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18101                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18102                                    }
18103                                }
18104                            }
18105                            break;
18106                    }
18107                }
18108
18109                applyOomAdjLocked(app, TOP_APP, true, now);
18110
18111                // Count the number of process types.
18112                switch (app.curProcState) {
18113                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18114                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18115                        mNumCachedHiddenProcs++;
18116                        numCached++;
18117                        if (numCached > cachedProcessLimit) {
18118                            app.kill("cached #" + numCached, true);
18119                        }
18120                        break;
18121                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18122                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18123                                && app.lastActivityTime < oldTime) {
18124                            app.kill("empty for "
18125                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18126                                    / 1000) + "s", true);
18127                        } else {
18128                            numEmpty++;
18129                            if (numEmpty > emptyProcessLimit) {
18130                                app.kill("empty #" + numEmpty, true);
18131                            }
18132                        }
18133                        break;
18134                    default:
18135                        mNumNonCachedProcs++;
18136                        break;
18137                }
18138
18139                if (app.isolated && app.services.size() <= 0) {
18140                    // If this is an isolated process, and there are no
18141                    // services running in it, then the process is no longer
18142                    // needed.  We agressively kill these because we can by
18143                    // definition not re-use the same process again, and it is
18144                    // good to avoid having whatever code was running in them
18145                    // left sitting around after no longer needed.
18146                    app.kill("isolated not needed", true);
18147                }
18148
18149                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18150                        && !app.killedByAm) {
18151                    numTrimming++;
18152                }
18153            }
18154        }
18155
18156        mNumServiceProcs = mNewNumServiceProcs;
18157
18158        // Now determine the memory trimming level of background processes.
18159        // Unfortunately we need to start at the back of the list to do this
18160        // properly.  We only do this if the number of background apps we
18161        // are managing to keep around is less than half the maximum we desire;
18162        // if we are keeping a good number around, we'll let them use whatever
18163        // memory they want.
18164        final int numCachedAndEmpty = numCached + numEmpty;
18165        int memFactor;
18166        if (numCached <= ProcessList.TRIM_CACHED_APPS
18167                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18168            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18169                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18170            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18171                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18172            } else {
18173                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18174            }
18175        } else {
18176            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18177        }
18178        // We always allow the memory level to go up (better).  We only allow it to go
18179        // down if we are in a state where that is allowed, *and* the total number of processes
18180        // has gone down since last time.
18181        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18182                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18183                + " last=" + mLastNumProcesses);
18184        if (memFactor > mLastMemoryLevel) {
18185            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18186                memFactor = mLastMemoryLevel;
18187                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18188            }
18189        }
18190        mLastMemoryLevel = memFactor;
18191        mLastNumProcesses = mLruProcesses.size();
18192        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18193        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18194        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18195            if (mLowRamStartTime == 0) {
18196                mLowRamStartTime = now;
18197            }
18198            int step = 0;
18199            int fgTrimLevel;
18200            switch (memFactor) {
18201                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18202                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18203                    break;
18204                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18205                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18206                    break;
18207                default:
18208                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18209                    break;
18210            }
18211            int factor = numTrimming/3;
18212            int minFactor = 2;
18213            if (mHomeProcess != null) minFactor++;
18214            if (mPreviousProcess != null) minFactor++;
18215            if (factor < minFactor) factor = minFactor;
18216            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18217            for (int i=N-1; i>=0; i--) {
18218                ProcessRecord app = mLruProcesses.get(i);
18219                if (allChanged || app.procStateChanged) {
18220                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18221                    app.procStateChanged = false;
18222                }
18223                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18224                        && !app.killedByAm) {
18225                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18226                        try {
18227                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18228                                    "Trimming memory of " + app.processName
18229                                    + " to " + curLevel);
18230                            app.thread.scheduleTrimMemory(curLevel);
18231                        } catch (RemoteException e) {
18232                        }
18233                        if (false) {
18234                            // For now we won't do this; our memory trimming seems
18235                            // to be good enough at this point that destroying
18236                            // activities causes more harm than good.
18237                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18238                                    && app != mHomeProcess && app != mPreviousProcess) {
18239                                // Need to do this on its own message because the stack may not
18240                                // be in a consistent state at this point.
18241                                // For these apps we will also finish their activities
18242                                // to help them free memory.
18243                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18244                            }
18245                        }
18246                    }
18247                    app.trimMemoryLevel = curLevel;
18248                    step++;
18249                    if (step >= factor) {
18250                        step = 0;
18251                        switch (curLevel) {
18252                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18253                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18254                                break;
18255                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18256                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18257                                break;
18258                        }
18259                    }
18260                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18261                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18262                            && app.thread != null) {
18263                        try {
18264                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18265                                    "Trimming memory of heavy-weight " + app.processName
18266                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18267                            app.thread.scheduleTrimMemory(
18268                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18269                        } catch (RemoteException e) {
18270                        }
18271                    }
18272                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18273                } else {
18274                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18275                            || app.systemNoUi) && app.pendingUiClean) {
18276                        // If this application is now in the background and it
18277                        // had done UI, then give it the special trim level to
18278                        // have it free UI resources.
18279                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18280                        if (app.trimMemoryLevel < level && app.thread != null) {
18281                            try {
18282                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18283                                        "Trimming memory of bg-ui " + app.processName
18284                                        + " to " + level);
18285                                app.thread.scheduleTrimMemory(level);
18286                            } catch (RemoteException e) {
18287                            }
18288                        }
18289                        app.pendingUiClean = false;
18290                    }
18291                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18292                        try {
18293                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18294                                    "Trimming memory of fg " + app.processName
18295                                    + " to " + fgTrimLevel);
18296                            app.thread.scheduleTrimMemory(fgTrimLevel);
18297                        } catch (RemoteException e) {
18298                        }
18299                    }
18300                    app.trimMemoryLevel = fgTrimLevel;
18301                }
18302            }
18303        } else {
18304            if (mLowRamStartTime != 0) {
18305                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18306                mLowRamStartTime = 0;
18307            }
18308            for (int i=N-1; i>=0; i--) {
18309                ProcessRecord app = mLruProcesses.get(i);
18310                if (allChanged || app.procStateChanged) {
18311                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18312                    app.procStateChanged = false;
18313                }
18314                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18315                        || app.systemNoUi) && app.pendingUiClean) {
18316                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18317                            && app.thread != null) {
18318                        try {
18319                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18320                                    "Trimming memory of ui hidden " + app.processName
18321                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18322                            app.thread.scheduleTrimMemory(
18323                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18324                        } catch (RemoteException e) {
18325                        }
18326                    }
18327                    app.pendingUiClean = false;
18328                }
18329                app.trimMemoryLevel = 0;
18330            }
18331        }
18332
18333        if (mAlwaysFinishActivities) {
18334            // Need to do this on its own message because the stack may not
18335            // be in a consistent state at this point.
18336            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18337        }
18338
18339        if (allChanged) {
18340            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18341        }
18342
18343        if (mProcessStats.shouldWriteNowLocked(now)) {
18344            mHandler.post(new Runnable() {
18345                @Override public void run() {
18346                    synchronized (ActivityManagerService.this) {
18347                        mProcessStats.writeStateAsyncLocked();
18348                    }
18349                }
18350            });
18351        }
18352
18353        if (DEBUG_OOM_ADJ) {
18354            if (false) {
18355                RuntimeException here = new RuntimeException("here");
18356                here.fillInStackTrace();
18357                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18358            } else {
18359                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18360            }
18361        }
18362    }
18363
18364    final void trimApplications() {
18365        synchronized (this) {
18366            int i;
18367
18368            // First remove any unused application processes whose package
18369            // has been removed.
18370            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18371                final ProcessRecord app = mRemovedProcesses.get(i);
18372                if (app.activities.size() == 0
18373                        && app.curReceiver == null && app.services.size() == 0) {
18374                    Slog.i(
18375                        TAG, "Exiting empty application process "
18376                        + app.processName + " ("
18377                        + (app.thread != null ? app.thread.asBinder() : null)
18378                        + ")\n");
18379                    if (app.pid > 0 && app.pid != MY_PID) {
18380                        app.kill("empty", false);
18381                    } else {
18382                        try {
18383                            app.thread.scheduleExit();
18384                        } catch (Exception e) {
18385                            // Ignore exceptions.
18386                        }
18387                    }
18388                    cleanUpApplicationRecordLocked(app, false, true, -1);
18389                    mRemovedProcesses.remove(i);
18390
18391                    if (app.persistent) {
18392                        addAppLocked(app.info, false, null /* ABI override */);
18393                    }
18394                }
18395            }
18396
18397            // Now update the oom adj for all processes.
18398            updateOomAdjLocked();
18399        }
18400    }
18401
18402    /** This method sends the specified signal to each of the persistent apps */
18403    public void signalPersistentProcesses(int sig) throws RemoteException {
18404        if (sig != Process.SIGNAL_USR1) {
18405            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18406        }
18407
18408        synchronized (this) {
18409            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18410                    != PackageManager.PERMISSION_GRANTED) {
18411                throw new SecurityException("Requires permission "
18412                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18413            }
18414
18415            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18416                ProcessRecord r = mLruProcesses.get(i);
18417                if (r.thread != null && r.persistent) {
18418                    Process.sendSignal(r.pid, sig);
18419                }
18420            }
18421        }
18422    }
18423
18424    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18425        if (proc == null || proc == mProfileProc) {
18426            proc = mProfileProc;
18427            profileType = mProfileType;
18428            clearProfilerLocked();
18429        }
18430        if (proc == null) {
18431            return;
18432        }
18433        try {
18434            proc.thread.profilerControl(false, null, profileType);
18435        } catch (RemoteException e) {
18436            throw new IllegalStateException("Process disappeared");
18437        }
18438    }
18439
18440    private void clearProfilerLocked() {
18441        if (mProfileFd != null) {
18442            try {
18443                mProfileFd.close();
18444            } catch (IOException e) {
18445            }
18446        }
18447        mProfileApp = null;
18448        mProfileProc = null;
18449        mProfileFile = null;
18450        mProfileType = 0;
18451        mAutoStopProfiler = false;
18452        mSamplingInterval = 0;
18453    }
18454
18455    public boolean profileControl(String process, int userId, boolean start,
18456            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18457
18458        try {
18459            synchronized (this) {
18460                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18461                // its own permission.
18462                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18463                        != PackageManager.PERMISSION_GRANTED) {
18464                    throw new SecurityException("Requires permission "
18465                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18466                }
18467
18468                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18469                    throw new IllegalArgumentException("null profile info or fd");
18470                }
18471
18472                ProcessRecord proc = null;
18473                if (process != null) {
18474                    proc = findProcessLocked(process, userId, "profileControl");
18475                }
18476
18477                if (start && (proc == null || proc.thread == null)) {
18478                    throw new IllegalArgumentException("Unknown process: " + process);
18479                }
18480
18481                if (start) {
18482                    stopProfilerLocked(null, 0);
18483                    setProfileApp(proc.info, proc.processName, profilerInfo);
18484                    mProfileProc = proc;
18485                    mProfileType = profileType;
18486                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18487                    try {
18488                        fd = fd.dup();
18489                    } catch (IOException e) {
18490                        fd = null;
18491                    }
18492                    profilerInfo.profileFd = fd;
18493                    proc.thread.profilerControl(start, profilerInfo, profileType);
18494                    fd = null;
18495                    mProfileFd = null;
18496                } else {
18497                    stopProfilerLocked(proc, profileType);
18498                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18499                        try {
18500                            profilerInfo.profileFd.close();
18501                        } catch (IOException e) {
18502                        }
18503                    }
18504                }
18505
18506                return true;
18507            }
18508        } catch (RemoteException e) {
18509            throw new IllegalStateException("Process disappeared");
18510        } finally {
18511            if (profilerInfo != null && profilerInfo.profileFd != null) {
18512                try {
18513                    profilerInfo.profileFd.close();
18514                } catch (IOException e) {
18515                }
18516            }
18517        }
18518    }
18519
18520    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18521        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18522                userId, true, ALLOW_FULL_ONLY, callName, null);
18523        ProcessRecord proc = null;
18524        try {
18525            int pid = Integer.parseInt(process);
18526            synchronized (mPidsSelfLocked) {
18527                proc = mPidsSelfLocked.get(pid);
18528            }
18529        } catch (NumberFormatException e) {
18530        }
18531
18532        if (proc == null) {
18533            ArrayMap<String, SparseArray<ProcessRecord>> all
18534                    = mProcessNames.getMap();
18535            SparseArray<ProcessRecord> procs = all.get(process);
18536            if (procs != null && procs.size() > 0) {
18537                proc = procs.valueAt(0);
18538                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18539                    for (int i=1; i<procs.size(); i++) {
18540                        ProcessRecord thisProc = procs.valueAt(i);
18541                        if (thisProc.userId == userId) {
18542                            proc = thisProc;
18543                            break;
18544                        }
18545                    }
18546                }
18547            }
18548        }
18549
18550        return proc;
18551    }
18552
18553    public boolean dumpHeap(String process, int userId, boolean managed,
18554            String path, ParcelFileDescriptor fd) throws RemoteException {
18555
18556        try {
18557            synchronized (this) {
18558                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18559                // its own permission (same as profileControl).
18560                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18561                        != PackageManager.PERMISSION_GRANTED) {
18562                    throw new SecurityException("Requires permission "
18563                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18564                }
18565
18566                if (fd == null) {
18567                    throw new IllegalArgumentException("null fd");
18568                }
18569
18570                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18571                if (proc == null || proc.thread == null) {
18572                    throw new IllegalArgumentException("Unknown process: " + process);
18573                }
18574
18575                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18576                if (!isDebuggable) {
18577                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18578                        throw new SecurityException("Process not debuggable: " + proc);
18579                    }
18580                }
18581
18582                proc.thread.dumpHeap(managed, path, fd);
18583                fd = null;
18584                return true;
18585            }
18586        } catch (RemoteException e) {
18587            throw new IllegalStateException("Process disappeared");
18588        } finally {
18589            if (fd != null) {
18590                try {
18591                    fd.close();
18592                } catch (IOException e) {
18593                }
18594            }
18595        }
18596    }
18597
18598    @Override
18599    public void setDumpHeapDebugLimit(String processName, long maxMemSize) {
18600        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
18601                "setDumpHeapDebugLimit()");
18602        synchronized (this) {
18603            if (maxMemSize > 0) {
18604                mMemWatchProcesses.put(processName, maxMemSize);
18605                mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
18606            } else {
18607                mMemWatchProcesses.remove(processName);
18608            }
18609        }
18610    }
18611
18612    @Override
18613    public void dumpHeapFinished(String path) {
18614        synchronized (this) {
18615            if (Binder.getCallingPid() != mMemWatchDumpPid) {
18616                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
18617                        + " does not match last pid " + mMemWatchDumpPid);
18618                return;
18619            }
18620            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
18621                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
18622                        + " does not match last path " + mMemWatchDumpFile);
18623                return;
18624            }
18625            if (DEBUG_PSS) Slog.d(TAG, "Dump heap finished for " + path);
18626            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
18627        }
18628    }
18629
18630    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18631    public void monitor() {
18632        synchronized (this) { }
18633    }
18634
18635    void onCoreSettingsChange(Bundle settings) {
18636        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18637            ProcessRecord processRecord = mLruProcesses.get(i);
18638            try {
18639                if (processRecord.thread != null) {
18640                    processRecord.thread.setCoreSettings(settings);
18641                }
18642            } catch (RemoteException re) {
18643                /* ignore */
18644            }
18645        }
18646    }
18647
18648    // Multi-user methods
18649
18650    /**
18651     * Start user, if its not already running, but don't bring it to foreground.
18652     */
18653    @Override
18654    public boolean startUserInBackground(final int userId) {
18655        return startUser(userId, /* foreground */ false);
18656    }
18657
18658    /**
18659     * Start user, if its not already running, and bring it to foreground.
18660     */
18661    boolean startUserInForeground(final int userId, Dialog dlg) {
18662        boolean result = startUser(userId, /* foreground */ true);
18663        dlg.dismiss();
18664        return result;
18665    }
18666
18667    /**
18668     * Refreshes the list of users related to the current user when either a
18669     * user switch happens or when a new related user is started in the
18670     * background.
18671     */
18672    private void updateCurrentProfileIdsLocked() {
18673        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18674                mCurrentUserId, false /* enabledOnly */);
18675        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18676        for (int i = 0; i < currentProfileIds.length; i++) {
18677            currentProfileIds[i] = profiles.get(i).id;
18678        }
18679        mCurrentProfileIds = currentProfileIds;
18680
18681        synchronized (mUserProfileGroupIdsSelfLocked) {
18682            mUserProfileGroupIdsSelfLocked.clear();
18683            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18684            for (int i = 0; i < users.size(); i++) {
18685                UserInfo user = users.get(i);
18686                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18687                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18688                }
18689            }
18690        }
18691    }
18692
18693    private Set<Integer> getProfileIdsLocked(int userId) {
18694        Set<Integer> userIds = new HashSet<Integer>();
18695        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18696                userId, false /* enabledOnly */);
18697        for (UserInfo user : profiles) {
18698            userIds.add(Integer.valueOf(user.id));
18699        }
18700        return userIds;
18701    }
18702
18703    @Override
18704    public boolean switchUser(final int userId) {
18705        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18706        String userName;
18707        synchronized (this) {
18708            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18709            if (userInfo == null) {
18710                Slog.w(TAG, "No user info for user #" + userId);
18711                return false;
18712            }
18713            if (userInfo.isManagedProfile()) {
18714                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18715                return false;
18716            }
18717            userName = userInfo.name;
18718            mTargetUserId = userId;
18719        }
18720        mHandler.removeMessages(START_USER_SWITCH_MSG);
18721        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18722        return true;
18723    }
18724
18725    private void showUserSwitchDialog(int userId, String userName) {
18726        // The dialog will show and then initiate the user switch by calling startUserInForeground
18727        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18728                true /* above system */);
18729        d.show();
18730    }
18731
18732    private boolean startUser(final int userId, final boolean foreground) {
18733        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18734                != PackageManager.PERMISSION_GRANTED) {
18735            String msg = "Permission Denial: switchUser() from pid="
18736                    + Binder.getCallingPid()
18737                    + ", uid=" + Binder.getCallingUid()
18738                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18739            Slog.w(TAG, msg);
18740            throw new SecurityException(msg);
18741        }
18742
18743        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18744
18745        final long ident = Binder.clearCallingIdentity();
18746        try {
18747            synchronized (this) {
18748                final int oldUserId = mCurrentUserId;
18749                if (oldUserId == userId) {
18750                    return true;
18751                }
18752
18753                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
18754                        "startUser");
18755
18756                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18757                if (userInfo == null) {
18758                    Slog.w(TAG, "No user info for user #" + userId);
18759                    return false;
18760                }
18761                if (foreground && userInfo.isManagedProfile()) {
18762                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18763                    return false;
18764                }
18765
18766                if (foreground) {
18767                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18768                            R.anim.screen_user_enter);
18769                }
18770
18771                boolean needStart = false;
18772
18773                // If the user we are switching to is not currently started, then
18774                // we need to start it now.
18775                if (mStartedUsers.get(userId) == null) {
18776                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18777                    updateStartedUserArrayLocked();
18778                    needStart = true;
18779                }
18780
18781                final Integer userIdInt = Integer.valueOf(userId);
18782                mUserLru.remove(userIdInt);
18783                mUserLru.add(userIdInt);
18784
18785                if (foreground) {
18786                    mCurrentUserId = userId;
18787                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18788                    updateCurrentProfileIdsLocked();
18789                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18790                    // Once the internal notion of the active user has switched, we lock the device
18791                    // with the option to show the user switcher on the keyguard.
18792                    mWindowManager.lockNow(null);
18793                } else {
18794                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18795                    updateCurrentProfileIdsLocked();
18796                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18797                    mUserLru.remove(currentUserIdInt);
18798                    mUserLru.add(currentUserIdInt);
18799                }
18800
18801                final UserStartedState uss = mStartedUsers.get(userId);
18802
18803                // Make sure user is in the started state.  If it is currently
18804                // stopping, we need to knock that off.
18805                if (uss.mState == UserStartedState.STATE_STOPPING) {
18806                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18807                    // so we can just fairly silently bring the user back from
18808                    // the almost-dead.
18809                    uss.mState = UserStartedState.STATE_RUNNING;
18810                    updateStartedUserArrayLocked();
18811                    needStart = true;
18812                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18813                    // This means ACTION_SHUTDOWN has been sent, so we will
18814                    // need to treat this as a new boot of the user.
18815                    uss.mState = UserStartedState.STATE_BOOTING;
18816                    updateStartedUserArrayLocked();
18817                    needStart = true;
18818                }
18819
18820                if (uss.mState == UserStartedState.STATE_BOOTING) {
18821                    // Booting up a new user, need to tell system services about it.
18822                    // Note that this is on the same handler as scheduling of broadcasts,
18823                    // which is important because it needs to go first.
18824                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18825                }
18826
18827                if (foreground) {
18828                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18829                            oldUserId));
18830                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18831                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18832                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18833                            oldUserId, userId, uss));
18834                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18835                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18836                }
18837
18838                if (needStart) {
18839                    // Send USER_STARTED broadcast
18840                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18841                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18842                            | Intent.FLAG_RECEIVER_FOREGROUND);
18843                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18844                    broadcastIntentLocked(null, null, intent,
18845                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18846                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18847                }
18848
18849                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18850                    if (userId != UserHandle.USER_OWNER) {
18851                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18852                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18853                        broadcastIntentLocked(null, null, intent, null,
18854                                new IIntentReceiver.Stub() {
18855                                    public void performReceive(Intent intent, int resultCode,
18856                                            String data, Bundle extras, boolean ordered,
18857                                            boolean sticky, int sendingUser) {
18858                                        onUserInitialized(uss, foreground, oldUserId, userId);
18859                                    }
18860                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18861                                true, false, MY_PID, Process.SYSTEM_UID,
18862                                userId);
18863                        uss.initializing = true;
18864                    } else {
18865                        getUserManagerLocked().makeInitialized(userInfo.id);
18866                    }
18867                }
18868
18869                if (foreground) {
18870                    if (!uss.initializing) {
18871                        moveUserToForeground(uss, oldUserId, userId);
18872                    }
18873                } else {
18874                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18875                }
18876
18877                if (needStart) {
18878                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18879                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18880                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18881                    broadcastIntentLocked(null, null, intent,
18882                            null, new IIntentReceiver.Stub() {
18883                                @Override
18884                                public void performReceive(Intent intent, int resultCode, String data,
18885                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18886                                        throws RemoteException {
18887                                }
18888                            }, 0, null, null,
18889                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18890                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18891                }
18892            }
18893        } finally {
18894            Binder.restoreCallingIdentity(ident);
18895        }
18896
18897        return true;
18898    }
18899
18900    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18901        long ident = Binder.clearCallingIdentity();
18902        try {
18903            Intent intent;
18904            if (oldUserId >= 0) {
18905                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18906                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18907                int count = profiles.size();
18908                for (int i = 0; i < count; i++) {
18909                    int profileUserId = profiles.get(i).id;
18910                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18911                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18912                            | Intent.FLAG_RECEIVER_FOREGROUND);
18913                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18914                    broadcastIntentLocked(null, null, intent,
18915                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18916                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18917                }
18918            }
18919            if (newUserId >= 0) {
18920                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18921                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18922                int count = profiles.size();
18923                for (int i = 0; i < count; i++) {
18924                    int profileUserId = profiles.get(i).id;
18925                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18926                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18927                            | Intent.FLAG_RECEIVER_FOREGROUND);
18928                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18929                    broadcastIntentLocked(null, null, intent,
18930                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18931                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18932                }
18933                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18934                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18935                        | Intent.FLAG_RECEIVER_FOREGROUND);
18936                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18937                broadcastIntentLocked(null, null, intent,
18938                        null, null, 0, null, null,
18939                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18940                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18941            }
18942        } finally {
18943            Binder.restoreCallingIdentity(ident);
18944        }
18945    }
18946
18947    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18948            final int newUserId) {
18949        final int N = mUserSwitchObservers.beginBroadcast();
18950        if (N > 0) {
18951            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18952                int mCount = 0;
18953                @Override
18954                public void sendResult(Bundle data) throws RemoteException {
18955                    synchronized (ActivityManagerService.this) {
18956                        if (mCurUserSwitchCallback == this) {
18957                            mCount++;
18958                            if (mCount == N) {
18959                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18960                            }
18961                        }
18962                    }
18963                }
18964            };
18965            synchronized (this) {
18966                uss.switching = true;
18967                mCurUserSwitchCallback = callback;
18968            }
18969            for (int i=0; i<N; i++) {
18970                try {
18971                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18972                            newUserId, callback);
18973                } catch (RemoteException e) {
18974                }
18975            }
18976        } else {
18977            synchronized (this) {
18978                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18979            }
18980        }
18981        mUserSwitchObservers.finishBroadcast();
18982    }
18983
18984    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18985        synchronized (this) {
18986            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18987            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18988        }
18989    }
18990
18991    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18992        mCurUserSwitchCallback = null;
18993        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18994        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18995                oldUserId, newUserId, uss));
18996    }
18997
18998    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18999        synchronized (this) {
19000            if (foreground) {
19001                moveUserToForeground(uss, oldUserId, newUserId);
19002            }
19003        }
19004
19005        completeSwitchAndInitalize(uss, newUserId, true, false);
19006    }
19007
19008    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19009        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19010        if (homeInFront) {
19011            startHomeActivityLocked(newUserId, "moveUserToFroreground");
19012        } else {
19013            mStackSupervisor.resumeTopActivitiesLocked();
19014        }
19015        EventLogTags.writeAmSwitchUser(newUserId);
19016        getUserManagerLocked().userForeground(newUserId);
19017        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19018    }
19019
19020    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19021        completeSwitchAndInitalize(uss, newUserId, false, true);
19022    }
19023
19024    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19025            boolean clearInitializing, boolean clearSwitching) {
19026        boolean unfrozen = false;
19027        synchronized (this) {
19028            if (clearInitializing) {
19029                uss.initializing = false;
19030                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19031            }
19032            if (clearSwitching) {
19033                uss.switching = false;
19034            }
19035            if (!uss.switching && !uss.initializing) {
19036                mWindowManager.stopFreezingScreen();
19037                unfrozen = true;
19038            }
19039        }
19040        if (unfrozen) {
19041            final int N = mUserSwitchObservers.beginBroadcast();
19042            for (int i=0; i<N; i++) {
19043                try {
19044                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19045                } catch (RemoteException e) {
19046                }
19047            }
19048            mUserSwitchObservers.finishBroadcast();
19049        }
19050        stopGuestUserIfBackground();
19051    }
19052
19053    /**
19054     * Stops the guest user if it has gone to the background.
19055     */
19056    private void stopGuestUserIfBackground() {
19057        synchronized (this) {
19058            final int num = mUserLru.size();
19059            for (int i = 0; i < num; i++) {
19060                Integer oldUserId = mUserLru.get(i);
19061                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19062                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19063                        || oldUss.mState == UserStartedState.STATE_STOPPING
19064                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19065                    continue;
19066                }
19067                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19068                if (userInfo.isGuest()) {
19069                    // This is a user to be stopped.
19070                    stopUserLocked(oldUserId, null);
19071                    break;
19072                }
19073            }
19074        }
19075    }
19076
19077    void scheduleStartProfilesLocked() {
19078        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19079            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19080                    DateUtils.SECOND_IN_MILLIS);
19081        }
19082    }
19083
19084    void startProfilesLocked() {
19085        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19086        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19087                mCurrentUserId, false /* enabledOnly */);
19088        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19089        for (UserInfo user : profiles) {
19090            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19091                    && user.id != mCurrentUserId) {
19092                toStart.add(user);
19093            }
19094        }
19095        final int n = toStart.size();
19096        int i = 0;
19097        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19098            startUserInBackground(toStart.get(i).id);
19099        }
19100        if (i < n) {
19101            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19102        }
19103    }
19104
19105    void finishUserBoot(UserStartedState uss) {
19106        synchronized (this) {
19107            if (uss.mState == UserStartedState.STATE_BOOTING
19108                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19109                uss.mState = UserStartedState.STATE_RUNNING;
19110                final int userId = uss.mHandle.getIdentifier();
19111                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19112                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19113                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19114                broadcastIntentLocked(null, null, intent,
19115                        null, null, 0, null, null,
19116                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19117                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19118            }
19119        }
19120    }
19121
19122    void finishUserSwitch(UserStartedState uss) {
19123        synchronized (this) {
19124            finishUserBoot(uss);
19125
19126            startProfilesLocked();
19127
19128            int num = mUserLru.size();
19129            int i = 0;
19130            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19131                Integer oldUserId = mUserLru.get(i);
19132                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19133                if (oldUss == null) {
19134                    // Shouldn't happen, but be sane if it does.
19135                    mUserLru.remove(i);
19136                    num--;
19137                    continue;
19138                }
19139                if (oldUss.mState == UserStartedState.STATE_STOPPING
19140                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19141                    // This user is already stopping, doesn't count.
19142                    num--;
19143                    i++;
19144                    continue;
19145                }
19146                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19147                    // Owner and current can't be stopped, but count as running.
19148                    i++;
19149                    continue;
19150                }
19151                // This is a user to be stopped.
19152                stopUserLocked(oldUserId, null);
19153                num--;
19154                i++;
19155            }
19156        }
19157    }
19158
19159    @Override
19160    public int stopUser(final int userId, final IStopUserCallback callback) {
19161        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19162                != PackageManager.PERMISSION_GRANTED) {
19163            String msg = "Permission Denial: switchUser() from pid="
19164                    + Binder.getCallingPid()
19165                    + ", uid=" + Binder.getCallingUid()
19166                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19167            Slog.w(TAG, msg);
19168            throw new SecurityException(msg);
19169        }
19170        if (userId <= 0) {
19171            throw new IllegalArgumentException("Can't stop primary user " + userId);
19172        }
19173        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19174        synchronized (this) {
19175            return stopUserLocked(userId, callback);
19176        }
19177    }
19178
19179    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19180        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19181        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19182            return ActivityManager.USER_OP_IS_CURRENT;
19183        }
19184
19185        final UserStartedState uss = mStartedUsers.get(userId);
19186        if (uss == null) {
19187            // User is not started, nothing to do...  but we do need to
19188            // callback if requested.
19189            if (callback != null) {
19190                mHandler.post(new Runnable() {
19191                    @Override
19192                    public void run() {
19193                        try {
19194                            callback.userStopped(userId);
19195                        } catch (RemoteException e) {
19196                        }
19197                    }
19198                });
19199            }
19200            return ActivityManager.USER_OP_SUCCESS;
19201        }
19202
19203        if (callback != null) {
19204            uss.mStopCallbacks.add(callback);
19205        }
19206
19207        if (uss.mState != UserStartedState.STATE_STOPPING
19208                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19209            uss.mState = UserStartedState.STATE_STOPPING;
19210            updateStartedUserArrayLocked();
19211
19212            long ident = Binder.clearCallingIdentity();
19213            try {
19214                // We are going to broadcast ACTION_USER_STOPPING and then
19215                // once that is done send a final ACTION_SHUTDOWN and then
19216                // stop the user.
19217                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19218                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19219                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19220                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19221                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19222                // This is the result receiver for the final shutdown broadcast.
19223                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19224                    @Override
19225                    public void performReceive(Intent intent, int resultCode, String data,
19226                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19227                        finishUserStop(uss);
19228                    }
19229                };
19230                // This is the result receiver for the initial stopping broadcast.
19231                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19232                    @Override
19233                    public void performReceive(Intent intent, int resultCode, String data,
19234                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19235                        // On to the next.
19236                        synchronized (ActivityManagerService.this) {
19237                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19238                                // Whoops, we are being started back up.  Abort, abort!
19239                                return;
19240                            }
19241                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19242                        }
19243                        mBatteryStatsService.noteEvent(
19244                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19245                                Integer.toString(userId), userId);
19246                        mSystemServiceManager.stopUser(userId);
19247                        broadcastIntentLocked(null, null, shutdownIntent,
19248                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19249                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19250                    }
19251                };
19252                // Kick things off.
19253                broadcastIntentLocked(null, null, stoppingIntent,
19254                        null, stoppingReceiver, 0, null, null,
19255                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19256                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19257            } finally {
19258                Binder.restoreCallingIdentity(ident);
19259            }
19260        }
19261
19262        return ActivityManager.USER_OP_SUCCESS;
19263    }
19264
19265    void finishUserStop(UserStartedState uss) {
19266        final int userId = uss.mHandle.getIdentifier();
19267        boolean stopped;
19268        ArrayList<IStopUserCallback> callbacks;
19269        synchronized (this) {
19270            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19271            if (mStartedUsers.get(userId) != uss) {
19272                stopped = false;
19273            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19274                stopped = false;
19275            } else {
19276                stopped = true;
19277                // User can no longer run.
19278                mStartedUsers.remove(userId);
19279                mUserLru.remove(Integer.valueOf(userId));
19280                updateStartedUserArrayLocked();
19281
19282                // Clean up all state and processes associated with the user.
19283                // Kill all the processes for the user.
19284                forceStopUserLocked(userId, "finish user");
19285            }
19286
19287            // Explicitly remove the old information in mRecentTasks.
19288            mRecentTasks.removeTasksForUserLocked(userId);
19289        }
19290
19291        for (int i=0; i<callbacks.size(); i++) {
19292            try {
19293                if (stopped) callbacks.get(i).userStopped(userId);
19294                else callbacks.get(i).userStopAborted(userId);
19295            } catch (RemoteException e) {
19296            }
19297        }
19298
19299        if (stopped) {
19300            mSystemServiceManager.cleanupUser(userId);
19301            synchronized (this) {
19302                mStackSupervisor.removeUserLocked(userId);
19303            }
19304        }
19305    }
19306
19307    @Override
19308    public UserInfo getCurrentUser() {
19309        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19310                != PackageManager.PERMISSION_GRANTED) && (
19311                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19312                != PackageManager.PERMISSION_GRANTED)) {
19313            String msg = "Permission Denial: getCurrentUser() from pid="
19314                    + Binder.getCallingPid()
19315                    + ", uid=" + Binder.getCallingUid()
19316                    + " requires " + INTERACT_ACROSS_USERS;
19317            Slog.w(TAG, msg);
19318            throw new SecurityException(msg);
19319        }
19320        synchronized (this) {
19321            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19322            return getUserManagerLocked().getUserInfo(userId);
19323        }
19324    }
19325
19326    int getCurrentUserIdLocked() {
19327        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19328    }
19329
19330    @Override
19331    public boolean isUserRunning(int userId, boolean orStopped) {
19332        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19333                != PackageManager.PERMISSION_GRANTED) {
19334            String msg = "Permission Denial: isUserRunning() from pid="
19335                    + Binder.getCallingPid()
19336                    + ", uid=" + Binder.getCallingUid()
19337                    + " requires " + INTERACT_ACROSS_USERS;
19338            Slog.w(TAG, msg);
19339            throw new SecurityException(msg);
19340        }
19341        synchronized (this) {
19342            return isUserRunningLocked(userId, orStopped);
19343        }
19344    }
19345
19346    boolean isUserRunningLocked(int userId, boolean orStopped) {
19347        UserStartedState state = mStartedUsers.get(userId);
19348        if (state == null) {
19349            return false;
19350        }
19351        if (orStopped) {
19352            return true;
19353        }
19354        return state.mState != UserStartedState.STATE_STOPPING
19355                && state.mState != UserStartedState.STATE_SHUTDOWN;
19356    }
19357
19358    @Override
19359    public int[] getRunningUserIds() {
19360        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19361                != PackageManager.PERMISSION_GRANTED) {
19362            String msg = "Permission Denial: isUserRunning() from pid="
19363                    + Binder.getCallingPid()
19364                    + ", uid=" + Binder.getCallingUid()
19365                    + " requires " + INTERACT_ACROSS_USERS;
19366            Slog.w(TAG, msg);
19367            throw new SecurityException(msg);
19368        }
19369        synchronized (this) {
19370            return mStartedUserArray;
19371        }
19372    }
19373
19374    private void updateStartedUserArrayLocked() {
19375        int num = 0;
19376        for (int i=0; i<mStartedUsers.size();  i++) {
19377            UserStartedState uss = mStartedUsers.valueAt(i);
19378            // This list does not include stopping users.
19379            if (uss.mState != UserStartedState.STATE_STOPPING
19380                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19381                num++;
19382            }
19383        }
19384        mStartedUserArray = new int[num];
19385        num = 0;
19386        for (int i=0; i<mStartedUsers.size();  i++) {
19387            UserStartedState uss = mStartedUsers.valueAt(i);
19388            if (uss.mState != UserStartedState.STATE_STOPPING
19389                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19390                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19391                num++;
19392            }
19393        }
19394    }
19395
19396    @Override
19397    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19398        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19399                != PackageManager.PERMISSION_GRANTED) {
19400            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19401                    + Binder.getCallingPid()
19402                    + ", uid=" + Binder.getCallingUid()
19403                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19404            Slog.w(TAG, msg);
19405            throw new SecurityException(msg);
19406        }
19407
19408        mUserSwitchObservers.register(observer);
19409    }
19410
19411    @Override
19412    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19413        mUserSwitchObservers.unregister(observer);
19414    }
19415
19416    private boolean userExists(int userId) {
19417        if (userId == 0) {
19418            return true;
19419        }
19420        UserManagerService ums = getUserManagerLocked();
19421        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19422    }
19423
19424    int[] getUsersLocked() {
19425        UserManagerService ums = getUserManagerLocked();
19426        return ums != null ? ums.getUserIds() : new int[] { 0 };
19427    }
19428
19429    UserManagerService getUserManagerLocked() {
19430        if (mUserManager == null) {
19431            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19432            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19433        }
19434        return mUserManager;
19435    }
19436
19437    private int applyUserId(int uid, int userId) {
19438        return UserHandle.getUid(userId, uid);
19439    }
19440
19441    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19442        if (info == null) return null;
19443        ApplicationInfo newInfo = new ApplicationInfo(info);
19444        newInfo.uid = applyUserId(info.uid, userId);
19445        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19446                + info.packageName;
19447        return newInfo;
19448    }
19449
19450    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19451        if (aInfo == null
19452                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19453            return aInfo;
19454        }
19455
19456        ActivityInfo info = new ActivityInfo(aInfo);
19457        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19458        return info;
19459    }
19460
19461    private final class LocalService extends ActivityManagerInternal {
19462        @Override
19463        public void onWakefulnessChanged(int wakefulness) {
19464            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19465        }
19466
19467        @Override
19468        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19469                String processName, String abiOverride, int uid, Runnable crashHandler) {
19470            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19471                    processName, abiOverride, uid, crashHandler);
19472        }
19473    }
19474
19475    /**
19476     * An implementation of IAppTask, that allows an app to manage its own tasks via
19477     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19478     * only the process that calls getAppTasks() can call the AppTask methods.
19479     */
19480    class AppTaskImpl extends IAppTask.Stub {
19481        private int mTaskId;
19482        private int mCallingUid;
19483
19484        public AppTaskImpl(int taskId, int callingUid) {
19485            mTaskId = taskId;
19486            mCallingUid = callingUid;
19487        }
19488
19489        private void checkCaller() {
19490            if (mCallingUid != Binder.getCallingUid()) {
19491                throw new SecurityException("Caller " + mCallingUid
19492                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19493            }
19494        }
19495
19496        @Override
19497        public void finishAndRemoveTask() {
19498            checkCaller();
19499
19500            synchronized (ActivityManagerService.this) {
19501                long origId = Binder.clearCallingIdentity();
19502                try {
19503                    if (!removeTaskByIdLocked(mTaskId, false)) {
19504                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19505                    }
19506                } finally {
19507                    Binder.restoreCallingIdentity(origId);
19508                }
19509            }
19510        }
19511
19512        @Override
19513        public ActivityManager.RecentTaskInfo getTaskInfo() {
19514            checkCaller();
19515
19516            synchronized (ActivityManagerService.this) {
19517                long origId = Binder.clearCallingIdentity();
19518                try {
19519                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
19520                    if (tr == null) {
19521                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19522                    }
19523                    return createRecentTaskInfoFromTaskRecord(tr);
19524                } finally {
19525                    Binder.restoreCallingIdentity(origId);
19526                }
19527            }
19528        }
19529
19530        @Override
19531        public void moveToFront() {
19532            checkCaller();
19533            // Will bring task to front if it already has a root activity.
19534            startActivityFromRecentsInner(mTaskId, null);
19535        }
19536
19537        @Override
19538        public int startActivity(IBinder whoThread, String callingPackage,
19539                Intent intent, String resolvedType, Bundle options) {
19540            checkCaller();
19541
19542            int callingUser = UserHandle.getCallingUserId();
19543            TaskRecord tr;
19544            IApplicationThread appThread;
19545            synchronized (ActivityManagerService.this) {
19546                tr = mRecentTasks.taskForIdLocked(mTaskId);
19547                if (tr == null) {
19548                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19549                }
19550                appThread = ApplicationThreadNative.asInterface(whoThread);
19551                if (appThread == null) {
19552                    throw new IllegalArgumentException("Bad app thread " + appThread);
19553                }
19554            }
19555            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19556                    resolvedType, null, null, null, null, 0, 0, null, null,
19557                    null, options, callingUser, null, tr);
19558        }
19559
19560        @Override
19561        public void setExcludeFromRecents(boolean exclude) {
19562            checkCaller();
19563
19564            synchronized (ActivityManagerService.this) {
19565                long origId = Binder.clearCallingIdentity();
19566                try {
19567                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
19568                    if (tr == null) {
19569                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19570                    }
19571                    Intent intent = tr.getBaseIntent();
19572                    if (exclude) {
19573                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19574                    } else {
19575                        intent.setFlags(intent.getFlags()
19576                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19577                    }
19578                } finally {
19579                    Binder.restoreCallingIdentity(origId);
19580                }
19581            }
19582        }
19583    }
19584}
19585