ActivityManagerService.java revision bd39d50624ae702009ff6e7e15885de479a52800
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.TaskRecord.INVALID_TASK_ID;
34
35import android.Manifest;
36import android.app.AppOpsManager;
37import android.app.ApplicationThreadNative;
38import android.app.IActivityContainer;
39import android.app.IActivityContainerCallback;
40import android.app.IAppTask;
41import android.app.ITaskStackListener;
42import android.app.ProfilerInfo;
43import android.app.admin.DevicePolicyManager;
44import android.app.usage.UsageEvents;
45import android.app.usage.UsageStatsManagerInternal;
46import android.appwidget.AppWidgetManager;
47import android.content.res.Resources;
48import android.graphics.Bitmap;
49import android.graphics.Point;
50import android.graphics.Rect;
51import android.os.BatteryStats;
52import android.os.PersistableBundle;
53import android.os.storage.IMountService;
54import android.os.storage.StorageManager;
55import android.service.voice.IVoiceInteractionSession;
56import android.util.ArrayMap;
57import android.util.ArraySet;
58import android.util.SparseIntArray;
59
60import com.android.internal.R;
61import com.android.internal.annotations.GuardedBy;
62import com.android.internal.app.IAppOpsService;
63import com.android.internal.app.IVoiceInteractor;
64import com.android.internal.app.ProcessMap;
65import com.android.internal.app.ProcessStats;
66import com.android.internal.os.BackgroundThread;
67import com.android.internal.os.BatteryStatsImpl;
68import com.android.internal.os.ProcessCpuTracker;
69import com.android.internal.os.TransferPipe;
70import com.android.internal.os.Zygote;
71import com.android.internal.util.FastPrintWriter;
72import com.android.internal.util.FastXmlSerializer;
73import com.android.internal.util.MemInfoReader;
74import com.android.internal.util.Preconditions;
75import com.android.server.AppOpsService;
76import com.android.server.AttributeCache;
77import com.android.server.IntentResolver;
78import com.android.server.LocalServices;
79import com.android.server.ServiceThread;
80import com.android.server.SystemService;
81import com.android.server.SystemServiceManager;
82import com.android.server.Watchdog;
83import com.android.server.am.ActivityStack.ActivityState;
84import com.android.server.firewall.IntentFirewall;
85import com.android.server.pm.Installer;
86import com.android.server.pm.UserManagerService;
87import com.android.server.statusbar.StatusBarManagerInternal;
88import com.android.server.wm.AppTransition;
89import com.android.server.wm.WindowManagerService;
90
91import com.google.android.collect.Lists;
92import com.google.android.collect.Maps;
93
94import libcore.io.IoUtils;
95
96import org.xmlpull.v1.XmlPullParser;
97import org.xmlpull.v1.XmlPullParserException;
98import org.xmlpull.v1.XmlSerializer;
99
100import android.app.Activity;
101import android.app.ActivityManager;
102import android.app.ActivityManager.RunningTaskInfo;
103import android.app.ActivityManager.StackInfo;
104import android.app.ActivityManagerInternal;
105import android.app.ActivityManagerNative;
106import android.app.ActivityOptions;
107import android.app.ActivityThread;
108import android.app.AlertDialog;
109import android.app.AppGlobals;
110import android.app.ApplicationErrorReport;
111import android.app.Dialog;
112import android.app.IActivityController;
113import android.app.IApplicationThread;
114import android.app.IInstrumentationWatcher;
115import android.app.INotificationManager;
116import android.app.IProcessObserver;
117import android.app.IServiceConnection;
118import android.app.IStopUserCallback;
119import android.app.IUiAutomationConnection;
120import android.app.IUserSwitchObserver;
121import android.app.Instrumentation;
122import android.app.Notification;
123import android.app.NotificationManager;
124import android.app.PendingIntent;
125import android.app.backup.IBackupManager;
126import android.content.ActivityNotFoundException;
127import android.content.BroadcastReceiver;
128import android.content.ClipData;
129import android.content.ComponentCallbacks2;
130import android.content.ComponentName;
131import android.content.ContentProvider;
132import android.content.ContentResolver;
133import android.content.Context;
134import android.content.DialogInterface;
135import android.content.IContentProvider;
136import android.content.IIntentReceiver;
137import android.content.IIntentSender;
138import android.content.Intent;
139import android.content.IntentFilter;
140import android.content.IntentSender;
141import android.content.pm.ActivityInfo;
142import android.content.pm.ApplicationInfo;
143import android.content.pm.ConfigurationInfo;
144import android.content.pm.IPackageDataObserver;
145import android.content.pm.IPackageManager;
146import android.content.pm.InstrumentationInfo;
147import android.content.pm.PackageInfo;
148import android.content.pm.PackageManager;
149import android.content.pm.ParceledListSlice;
150import android.content.pm.UserInfo;
151import android.content.pm.PackageManager.NameNotFoundException;
152import android.content.pm.PathPermission;
153import android.content.pm.ProviderInfo;
154import android.content.pm.ResolveInfo;
155import android.content.pm.ServiceInfo;
156import android.content.res.CompatibilityInfo;
157import android.content.res.Configuration;
158import android.net.Proxy;
159import android.net.ProxyInfo;
160import android.net.Uri;
161import android.os.Binder;
162import android.os.Build;
163import android.os.Bundle;
164import android.os.Debug;
165import android.os.DropBoxManager;
166import android.os.Environment;
167import android.os.FactoryTest;
168import android.os.FileObserver;
169import android.os.FileUtils;
170import android.os.Handler;
171import android.os.IBinder;
172import android.os.IPermissionController;
173import android.os.IRemoteCallback;
174import android.os.IUserManager;
175import android.os.Looper;
176import android.os.Message;
177import android.os.Parcel;
178import android.os.ParcelFileDescriptor;
179import android.os.PowerManagerInternal;
180import android.os.Process;
181import android.os.RemoteCallbackList;
182import android.os.RemoteException;
183import android.os.SELinux;
184import android.os.ServiceManager;
185import android.os.StrictMode;
186import android.os.SystemClock;
187import android.os.SystemProperties;
188import android.os.UpdateLock;
189import android.os.UserHandle;
190import android.os.UserManager;
191import android.provider.Settings;
192import android.text.format.DateUtils;
193import android.text.format.Time;
194import android.util.AtomicFile;
195import android.util.EventLog;
196import android.util.Log;
197import android.util.Pair;
198import android.util.PrintWriterPrinter;
199import android.util.Slog;
200import android.util.SparseArray;
201import android.util.TimeUtils;
202import android.util.Xml;
203import android.view.Gravity;
204import android.view.LayoutInflater;
205import android.view.View;
206import android.view.WindowManager;
207
208import dalvik.system.VMRuntime;
209
210import java.io.BufferedInputStream;
211import java.io.BufferedOutputStream;
212import java.io.DataInputStream;
213import java.io.DataOutputStream;
214import java.io.File;
215import java.io.FileDescriptor;
216import java.io.FileInputStream;
217import java.io.FileNotFoundException;
218import java.io.FileOutputStream;
219import java.io.IOException;
220import java.io.InputStreamReader;
221import java.io.PrintWriter;
222import java.io.StringWriter;
223import java.lang.ref.WeakReference;
224import java.util.ArrayList;
225import java.util.Arrays;
226import java.util.Collections;
227import java.util.Comparator;
228import java.util.HashMap;
229import java.util.HashSet;
230import java.util.Iterator;
231import java.util.List;
232import java.util.Locale;
233import java.util.Map;
234import java.util.Set;
235import java.util.concurrent.atomic.AtomicBoolean;
236import java.util.concurrent.atomic.AtomicLong;
237
238public final class ActivityManagerService extends ActivityManagerNative
239        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
240
241    private static final String USER_DATA_DIR = "/data/user/";
242    // File that stores last updated system version and called preboot receivers
243    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
244
245    static final String TAG = "ActivityManager";
246    static final String TAG_MU = "ActivityManagerServiceMU";
247    static final boolean DEBUG = false;
248    static final boolean localLOGV = DEBUG;
249    static final boolean DEBUG_BACKUP = localLOGV || false;
250    static final boolean DEBUG_BROADCAST = localLOGV || false;
251    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
252    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
253    static final boolean DEBUG_CLEANUP = localLOGV || false;
254    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
255    static final boolean DEBUG_FOCUS = false;
256    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
257    static final boolean DEBUG_MU = localLOGV || false;
258    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
259    static final boolean DEBUG_LRU = localLOGV || false;
260    static final boolean DEBUG_PAUSE = localLOGV || false;
261    static final boolean DEBUG_POWER = localLOGV || false;
262    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
263    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
264    static final boolean DEBUG_PROCESSES = localLOGV || false;
265    static final boolean DEBUG_PROVIDER = localLOGV || false;
266    static final boolean DEBUG_RESULTS = localLOGV || false;
267    static final boolean DEBUG_SERVICE = localLOGV || false;
268    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
269    static final boolean DEBUG_STACK = localLOGV || false;
270    static final boolean DEBUG_SWITCH = localLOGV || false;
271    static final boolean DEBUG_TASKS = localLOGV || false;
272    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
273    static final boolean DEBUG_TRANSITION = localLOGV || false;
274    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
275    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
276    static final boolean DEBUG_VISBILITY = localLOGV || false;
277    static final boolean DEBUG_PSS = localLOGV || false;
278    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
279    static final boolean DEBUG_RECENTS = localLOGV || false;
280    static final boolean VALIDATE_TOKENS = false;
281    static final boolean SHOW_ACTIVITY_START_TIME = true;
282
283    // Control over CPU and battery monitoring.
284    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
285    static final boolean MONITOR_CPU_USAGE = true;
286    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
287    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
288    static final boolean MONITOR_THREAD_CPU_USAGE = false;
289
290    // The flags that are set for all calls we make to the package manager.
291    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
292
293    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
294
295    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
296
297    // Amount of time after a call to stopAppSwitches() during which we will
298    // prevent further untrusted switches from happening.
299    static final long APP_SWITCH_DELAY_TIME = 5*1000;
300
301    // How long we wait for a launched process to attach to the activity manager
302    // before we decide it's never going to come up for real.
303    static final int PROC_START_TIMEOUT = 10*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, when the process was
307    // started with a wrapper for instrumentation (such as Valgrind) because it
308    // could take much longer than usual.
309    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
310
311    // How long to wait after going idle before forcing apps to GC.
312    static final int GC_TIMEOUT = 5*1000;
313
314    // The minimum amount of time between successive GC requests for a process.
315    static final int GC_MIN_INTERVAL = 60*1000;
316
317    // The minimum amount of time between successive PSS requests for a process.
318    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
319
320    // The minimum amount of time between successive PSS requests for a process
321    // when the request is due to the memory state being lowered.
322    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
323
324    // The rate at which we check for apps using excessive power -- 15 mins.
325    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
326
327    // The minimum sample duration we will allow before deciding we have
328    // enough data on wake locks to start killing things.
329    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
330
331    // The minimum sample duration we will allow before deciding we have
332    // enough data on CPU usage to start killing things.
333    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
334
335    // How long we allow a receiver to run before giving up on it.
336    static final int BROADCAST_FG_TIMEOUT = 10*1000;
337    static final int BROADCAST_BG_TIMEOUT = 60*1000;
338
339    // How long we wait until we timeout on key dispatching.
340    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
341
342    // How long we wait until we timeout on key dispatching during instrumentation.
343    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
344
345    // Amount of time we wait for observers to handle a user switch before
346    // giving up on them and unfreezing the screen.
347    static final int USER_SWITCH_TIMEOUT = 2*1000;
348
349    // Maximum number of users we allow to be running at a time.
350    static final int MAX_RUNNING_USERS = 3;
351
352    // How long to wait in getAssistContextExtras for the activity and foreground services
353    // to respond with the result.
354    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
355
356    // Maximum number of persisted Uri grants a package is allowed
357    static final int MAX_PERSISTED_URI_GRANTS = 128;
358
359    static final int MY_PID = Process.myPid();
360
361    static final String[] EMPTY_STRING_ARRAY = new String[0];
362
363    // How many bytes to write into the dropbox log before truncating
364    static final int DROPBOX_MAX_SIZE = 256 * 1024;
365
366    // Access modes for handleIncomingUser.
367    static final int ALLOW_NON_FULL = 0;
368    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
369    static final int ALLOW_FULL_ONLY = 2;
370
371    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
372
373    // Delay in notifying task stack change listeners (in millis)
374    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
375
376    /** All system services */
377    SystemServiceManager mSystemServiceManager;
378
379    private Installer mInstaller;
380
381    /** Run all ActivityStacks through this */
382    ActivityStackSupervisor mStackSupervisor;
383
384    /** Task stack change listeners. */
385    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
386            new RemoteCallbackList<ITaskStackListener>();
387
388    public IntentFirewall mIntentFirewall;
389
390    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
391    // default actuion automatically.  Important for devices without direct input
392    // devices.
393    private boolean mShowDialogs = true;
394
395    BroadcastQueue mFgBroadcastQueue;
396    BroadcastQueue mBgBroadcastQueue;
397    // Convenient for easy iteration over the queues. Foreground is first
398    // so that dispatch of foreground broadcasts gets precedence.
399    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
400
401    BroadcastQueue broadcastQueueForIntent(Intent intent) {
402        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
403        if (DEBUG_BACKGROUND_BROADCAST) {
404            Slog.i(TAG, "Broadcast intent " + intent + " on "
405                    + (isFg ? "foreground" : "background")
406                    + " queue");
407        }
408        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
409    }
410
411    /**
412     * Activity we have told the window manager to have key focus.
413     */
414    ActivityRecord mFocusedActivity = null;
415
416    /**
417     * List of intents that were used to start the most recent tasks.
418     */
419    private final RecentTasks mRecentTasks;
420
421    /**
422     * For addAppTask: cached of the last activity component that was added.
423     */
424    ComponentName mLastAddedTaskComponent;
425
426    /**
427     * For addAppTask: cached of the last activity uid that was added.
428     */
429    int mLastAddedTaskUid;
430
431    /**
432     * For addAppTask: cached of the last ActivityInfo that was added.
433     */
434    ActivityInfo mLastAddedTaskActivity;
435
436    public class PendingAssistExtras extends Binder implements Runnable {
437        public final ActivityRecord activity;
438        public final Bundle extras;
439        public final Intent intent;
440        public final String hint;
441        public final int userHandle;
442        public boolean haveResult = false;
443        public Bundle result = null;
444        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
445                String _hint, int _userHandle) {
446            activity = _activity;
447            extras = _extras;
448            intent = _intent;
449            hint = _hint;
450            userHandle = _userHandle;
451        }
452        @Override
453        public void run() {
454            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
455            synchronized (this) {
456                haveResult = true;
457                notifyAll();
458            }
459        }
460    }
461
462    final ArrayList<PendingAssistExtras> mPendingAssistExtras
463            = new ArrayList<PendingAssistExtras>();
464
465    /**
466     * Process management.
467     */
468    final ProcessList mProcessList = new ProcessList();
469
470    /**
471     * All of the applications we currently have running organized by name.
472     * The keys are strings of the application package name (as
473     * returned by the package manager), and the keys are ApplicationRecord
474     * objects.
475     */
476    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
477
478    /**
479     * Tracking long-term execution of processes to look for abuse and other
480     * bad app behavior.
481     */
482    final ProcessStatsService mProcessStats;
483
484    /**
485     * The currently running isolated processes.
486     */
487    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
488
489    /**
490     * Counter for assigning isolated process uids, to avoid frequently reusing the
491     * same ones.
492     */
493    int mNextIsolatedProcessUid = 0;
494
495    /**
496     * The currently running heavy-weight process, if any.
497     */
498    ProcessRecord mHeavyWeightProcess = null;
499
500    /**
501     * The last time that various processes have crashed.
502     */
503    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
504
505    /**
506     * Information about a process that is currently marked as bad.
507     */
508    static final class BadProcessInfo {
509        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
510            this.time = time;
511            this.shortMsg = shortMsg;
512            this.longMsg = longMsg;
513            this.stack = stack;
514        }
515
516        final long time;
517        final String shortMsg;
518        final String longMsg;
519        final String stack;
520    }
521
522    /**
523     * Set of applications that we consider to be bad, and will reject
524     * incoming broadcasts from (which the user has no control over).
525     * Processes are added to this set when they have crashed twice within
526     * a minimum amount of time; they are removed from it when they are
527     * later restarted (hopefully due to some user action).  The value is the
528     * time it was added to the list.
529     */
530    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
531
532    /**
533     * All of the processes we currently have running organized by pid.
534     * The keys are the pid running the application.
535     *
536     * <p>NOTE: This object is protected by its own lock, NOT the global
537     * activity manager lock!
538     */
539    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
540
541    /**
542     * All of the processes that have been forced to be foreground.  The key
543     * is the pid of the caller who requested it (we hold a death
544     * link on it).
545     */
546    abstract class ForegroundToken implements IBinder.DeathRecipient {
547        int pid;
548        IBinder token;
549    }
550    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
551
552    /**
553     * List of records for processes that someone had tried to start before the
554     * system was ready.  We don't start them at that point, but ensure they
555     * are started by the time booting is complete.
556     */
557    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
558
559    /**
560     * List of persistent applications that are in the process
561     * of being started.
562     */
563    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Processes that are being forcibly torn down.
567     */
568    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
569
570    /**
571     * List of running applications, sorted by recent usage.
572     * The first entry in the list is the least recently used.
573     */
574    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
575
576    /**
577     * Where in mLruProcesses that the processes hosting activities start.
578     */
579    int mLruProcessActivityStart = 0;
580
581    /**
582     * Where in mLruProcesses that the processes hosting services start.
583     * This is after (lower index) than mLruProcessesActivityStart.
584     */
585    int mLruProcessServiceStart = 0;
586
587    /**
588     * List of processes that should gc as soon as things are idle.
589     */
590    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
591
592    /**
593     * Processes we want to collect PSS data from.
594     */
595    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
596
597    /**
598     * Last time we requested PSS data of all processes.
599     */
600    long mLastFullPssTime = SystemClock.uptimeMillis();
601
602    /**
603     * If set, the next time we collect PSS data we should do a full collection
604     * with data from native processes and the kernel.
605     */
606    boolean mFullPssPending = false;
607
608    /**
609     * This is the process holding what we currently consider to be
610     * the "home" activity.
611     */
612    ProcessRecord mHomeProcess;
613
614    /**
615     * This is the process holding the activity the user last visited that
616     * is in a different process from the one they are currently in.
617     */
618    ProcessRecord mPreviousProcess;
619
620    /**
621     * The time at which the previous process was last visible.
622     */
623    long mPreviousProcessVisibleTime;
624
625    /**
626     * Which uses have been started, so are allowed to run code.
627     */
628    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
629
630    /**
631     * LRU list of history of current users.  Most recently current is at the end.
632     */
633    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
634
635    /**
636     * Constant array of the users that are currently started.
637     */
638    int[] mStartedUserArray = new int[] { 0 };
639
640    /**
641     * Registered observers of the user switching mechanics.
642     */
643    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
644            = new RemoteCallbackList<IUserSwitchObserver>();
645
646    /**
647     * Currently active user switch.
648     */
649    Object mCurUserSwitchCallback;
650
651    /**
652     * Packages that the user has asked to have run in screen size
653     * compatibility mode instead of filling the screen.
654     */
655    final CompatModePackages mCompatModePackages;
656
657    /**
658     * Set of IntentSenderRecord objects that are currently active.
659     */
660    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
661            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
662
663    /**
664     * Fingerprints (hashCode()) of stack traces that we've
665     * already logged DropBox entries for.  Guarded by itself.  If
666     * something (rogue user app) forces this over
667     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
668     */
669    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
670    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
671
672    /**
673     * Strict Mode background batched logging state.
674     *
675     * The string buffer is guarded by itself, and its lock is also
676     * used to determine if another batched write is already
677     * in-flight.
678     */
679    private final StringBuilder mStrictModeBuffer = new StringBuilder();
680
681    /**
682     * Keeps track of all IIntentReceivers that have been registered for
683     * broadcasts.  Hash keys are the receiver IBinder, hash value is
684     * a ReceiverList.
685     */
686    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
687            new HashMap<IBinder, ReceiverList>();
688
689    /**
690     * Resolver for broadcast intents to registered receivers.
691     * Holds BroadcastFilter (subclass of IntentFilter).
692     */
693    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
694            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
695        @Override
696        protected boolean allowFilterResult(
697                BroadcastFilter filter, List<BroadcastFilter> dest) {
698            IBinder target = filter.receiverList.receiver.asBinder();
699            for (int i=dest.size()-1; i>=0; i--) {
700                if (dest.get(i).receiverList.receiver.asBinder() == target) {
701                    return false;
702                }
703            }
704            return true;
705        }
706
707        @Override
708        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
709            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
710                    || userId == filter.owningUserId) {
711                return super.newResult(filter, match, userId);
712            }
713            return null;
714        }
715
716        @Override
717        protected BroadcastFilter[] newArray(int size) {
718            return new BroadcastFilter[size];
719        }
720
721        @Override
722        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
723            return packageName.equals(filter.packageName);
724        }
725    };
726
727    /**
728     * State of all active sticky broadcasts per user.  Keys are the action of the
729     * sticky Intent, values are an ArrayList of all broadcasted intents with
730     * that action (which should usually be one).  The SparseArray is keyed
731     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
732     * for stickies that are sent to all users.
733     */
734    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
735            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
736
737    final ActiveServices mServices;
738
739    final static class Association {
740        final int mSourceUid;
741        final String mSourceProcess;
742        final int mTargetUid;
743        final ComponentName mTargetComponent;
744        final String mTargetProcess;
745
746        int mCount;
747        long mTime;
748
749        int mNesting;
750        long mStartTime;
751
752        Association(int sourceUid, String sourceProcess, int targetUid,
753                ComponentName targetComponent, String targetProcess) {
754            mSourceUid = sourceUid;
755            mSourceProcess = sourceProcess;
756            mTargetUid = targetUid;
757            mTargetComponent = targetComponent;
758            mTargetProcess = targetProcess;
759        }
760    }
761
762    /**
763     * When service association tracking is enabled, this is all of the associations we
764     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
765     * -> association data.
766     */
767    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
768            mAssociations = new SparseArray<>();
769    boolean mTrackingAssociations;
770
771    /**
772     * Backup/restore process management
773     */
774    String mBackupAppName = null;
775    BackupRecord mBackupTarget = null;
776
777    final ProviderMap mProviderMap;
778
779    /**
780     * List of content providers who have clients waiting for them.  The
781     * application is currently being launched and the provider will be
782     * removed from this list once it is published.
783     */
784    final ArrayList<ContentProviderRecord> mLaunchingProviders
785            = new ArrayList<ContentProviderRecord>();
786
787    /**
788     * File storing persisted {@link #mGrantedUriPermissions}.
789     */
790    private final AtomicFile mGrantFile;
791
792    /** XML constants used in {@link #mGrantFile} */
793    private static final String TAG_URI_GRANTS = "uri-grants";
794    private static final String TAG_URI_GRANT = "uri-grant";
795    private static final String ATTR_USER_HANDLE = "userHandle";
796    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
797    private static final String ATTR_TARGET_USER_ID = "targetUserId";
798    private static final String ATTR_SOURCE_PKG = "sourcePkg";
799    private static final String ATTR_TARGET_PKG = "targetPkg";
800    private static final String ATTR_URI = "uri";
801    private static final String ATTR_MODE_FLAGS = "modeFlags";
802    private static final String ATTR_CREATED_TIME = "createdTime";
803    private static final String ATTR_PREFIX = "prefix";
804
805    /**
806     * Global set of specific {@link Uri} permissions that have been granted.
807     * This optimized lookup structure maps from {@link UriPermission#targetUid}
808     * to {@link UriPermission#uri} to {@link UriPermission}.
809     */
810    @GuardedBy("this")
811    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
812            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
813
814    public static class GrantUri {
815        public final int sourceUserId;
816        public final Uri uri;
817        public boolean prefix;
818
819        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
820            this.sourceUserId = sourceUserId;
821            this.uri = uri;
822            this.prefix = prefix;
823        }
824
825        @Override
826        public int hashCode() {
827            int hashCode = 1;
828            hashCode = 31 * hashCode + sourceUserId;
829            hashCode = 31 * hashCode + uri.hashCode();
830            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
831            return hashCode;
832        }
833
834        @Override
835        public boolean equals(Object o) {
836            if (o instanceof GrantUri) {
837                GrantUri other = (GrantUri) o;
838                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
839                        && prefix == other.prefix;
840            }
841            return false;
842        }
843
844        @Override
845        public String toString() {
846            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
847            if (prefix) result += " [prefix]";
848            return result;
849        }
850
851        public String toSafeString() {
852            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
853            if (prefix) result += " [prefix]";
854            return result;
855        }
856
857        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
858            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
859                    ContentProvider.getUriWithoutUserId(uri), false);
860        }
861    }
862
863    CoreSettingsObserver mCoreSettingsObserver;
864
865    /**
866     * Thread-local storage used to carry caller permissions over through
867     * indirect content-provider access.
868     */
869    private class Identity {
870        public final IBinder token;
871        public final int pid;
872        public final int uid;
873
874        Identity(IBinder _token, int _pid, int _uid) {
875            token = _token;
876            pid = _pid;
877            uid = _uid;
878        }
879    }
880
881    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
882
883    /**
884     * All information we have collected about the runtime performance of
885     * any user id that can impact battery performance.
886     */
887    final BatteryStatsService mBatteryStatsService;
888
889    /**
890     * Information about component usage
891     */
892    UsageStatsManagerInternal mUsageStatsService;
893
894    /**
895     * Information about and control over application operations
896     */
897    final AppOpsService mAppOpsService;
898
899    /**
900     * Save recent tasks information across reboots.
901     */
902    final TaskPersister mTaskPersister;
903
904    /**
905     * Current configuration information.  HistoryRecord objects are given
906     * a reference to this object to indicate which configuration they are
907     * currently running in, so this object must be kept immutable.
908     */
909    Configuration mConfiguration = new Configuration();
910
911    /**
912     * Current sequencing integer of the configuration, for skipping old
913     * configurations.
914     */
915    int mConfigurationSeq = 0;
916
917    /**
918     * Hardware-reported OpenGLES version.
919     */
920    final int GL_ES_VERSION;
921
922    /**
923     * List of initialization arguments to pass to all processes when binding applications to them.
924     * For example, references to the commonly used services.
925     */
926    HashMap<String, IBinder> mAppBindArgs;
927
928    /**
929     * Temporary to avoid allocations.  Protected by main lock.
930     */
931    final StringBuilder mStringBuilder = new StringBuilder(256);
932
933    /**
934     * Used to control how we initialize the service.
935     */
936    ComponentName mTopComponent;
937    String mTopAction = Intent.ACTION_MAIN;
938    String mTopData;
939    boolean mProcessesReady = false;
940    boolean mSystemReady = false;
941    boolean mBooting = false;
942    boolean mCallFinishBooting = false;
943    boolean mBootAnimationComplete = false;
944    boolean mWaitingUpdate = false;
945    boolean mDidUpdate = false;
946    boolean mOnBattery = false;
947    boolean mLaunchWarningShown = false;
948
949    Context mContext;
950
951    int mFactoryTest;
952
953    boolean mCheckedForSetup;
954
955    /**
956     * The time at which we will allow normal application switches again,
957     * after a call to {@link #stopAppSwitches()}.
958     */
959    long mAppSwitchesAllowedTime;
960
961    /**
962     * This is set to true after the first switch after mAppSwitchesAllowedTime
963     * is set; any switches after that will clear the time.
964     */
965    boolean mDidAppSwitch;
966
967    /**
968     * Last time (in realtime) at which we checked for power usage.
969     */
970    long mLastPowerCheckRealtime;
971
972    /**
973     * Last time (in uptime) at which we checked for power usage.
974     */
975    long mLastPowerCheckUptime;
976
977    /**
978     * Set while we are wanting to sleep, to prevent any
979     * activities from being started/resumed.
980     */
981    private boolean mSleeping = false;
982
983    /**
984     * Set while we are running a voice interaction.  This overrides
985     * sleeping while it is active.
986     */
987    private boolean mRunningVoice = false;
988
989    /**
990     * State of external calls telling us if the device is awake or asleep.
991     */
992    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
993
994    static final int LOCK_SCREEN_HIDDEN = 0;
995    static final int LOCK_SCREEN_LEAVING = 1;
996    static final int LOCK_SCREEN_SHOWN = 2;
997    /**
998     * State of external call telling us if the lock screen is shown.
999     */
1000    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1001
1002    /**
1003     * Set if we are shutting down the system, similar to sleeping.
1004     */
1005    boolean mShuttingDown = false;
1006
1007    /**
1008     * Current sequence id for oom_adj computation traversal.
1009     */
1010    int mAdjSeq = 0;
1011
1012    /**
1013     * Current sequence id for process LRU updating.
1014     */
1015    int mLruSeq = 0;
1016
1017    /**
1018     * Keep track of the non-cached/empty process we last found, to help
1019     * determine how to distribute cached/empty processes next time.
1020     */
1021    int mNumNonCachedProcs = 0;
1022
1023    /**
1024     * Keep track of the number of cached hidden procs, to balance oom adj
1025     * distribution between those and empty procs.
1026     */
1027    int mNumCachedHiddenProcs = 0;
1028
1029    /**
1030     * Keep track of the number of service processes we last found, to
1031     * determine on the next iteration which should be B services.
1032     */
1033    int mNumServiceProcs = 0;
1034    int mNewNumAServiceProcs = 0;
1035    int mNewNumServiceProcs = 0;
1036
1037    /**
1038     * Allow the current computed overall memory level of the system to go down?
1039     * This is set to false when we are killing processes for reasons other than
1040     * memory management, so that the now smaller process list will not be taken as
1041     * an indication that memory is tighter.
1042     */
1043    boolean mAllowLowerMemLevel = false;
1044
1045    /**
1046     * The last computed memory level, for holding when we are in a state that
1047     * processes are going away for other reasons.
1048     */
1049    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1050
1051    /**
1052     * The last total number of process we have, to determine if changes actually look
1053     * like a shrinking number of process due to lower RAM.
1054     */
1055    int mLastNumProcesses;
1056
1057    /**
1058     * The uptime of the last time we performed idle maintenance.
1059     */
1060    long mLastIdleTime = SystemClock.uptimeMillis();
1061
1062    /**
1063     * Total time spent with RAM that has been added in the past since the last idle time.
1064     */
1065    long mLowRamTimeSinceLastIdle = 0;
1066
1067    /**
1068     * If RAM is currently low, when that horrible situation started.
1069     */
1070    long mLowRamStartTime = 0;
1071
1072    /**
1073     * For reporting to battery stats the current top application.
1074     */
1075    private String mCurResumedPackage = null;
1076    private int mCurResumedUid = -1;
1077
1078    /**
1079     * For reporting to battery stats the apps currently running foreground
1080     * service.  The ProcessMap is package/uid tuples; each of these contain
1081     * an array of the currently foreground processes.
1082     */
1083    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1084            = new ProcessMap<ArrayList<ProcessRecord>>();
1085
1086    /**
1087     * This is set if we had to do a delayed dexopt of an app before launching
1088     * it, to increase the ANR timeouts in that case.
1089     */
1090    boolean mDidDexOpt;
1091
1092    /**
1093     * Set if the systemServer made a call to enterSafeMode.
1094     */
1095    boolean mSafeMode;
1096
1097    /**
1098     * If true, we are running under a test environment so will sample PSS from processes
1099     * much more rapidly to try to collect better data when the tests are rapidly
1100     * running through apps.
1101     */
1102    boolean mTestPssMode = false;
1103
1104    String mDebugApp = null;
1105    boolean mWaitForDebugger = false;
1106    boolean mDebugTransient = false;
1107    String mOrigDebugApp = null;
1108    boolean mOrigWaitForDebugger = false;
1109    boolean mAlwaysFinishActivities = false;
1110    IActivityController mController = null;
1111    String mProfileApp = null;
1112    ProcessRecord mProfileProc = null;
1113    String mProfileFile;
1114    ParcelFileDescriptor mProfileFd;
1115    int mSamplingInterval = 0;
1116    boolean mAutoStopProfiler = false;
1117    int mProfileType = 0;
1118    String mOpenGlTraceApp = null;
1119
1120    final long[] mTmpLong = new long[1];
1121
1122    static class ProcessChangeItem {
1123        static final int CHANGE_ACTIVITIES = 1<<0;
1124        static final int CHANGE_PROCESS_STATE = 1<<1;
1125        int changes;
1126        int uid;
1127        int pid;
1128        int processState;
1129        boolean foregroundActivities;
1130    }
1131
1132    final RemoteCallbackList<IProcessObserver> mProcessObservers
1133            = new RemoteCallbackList<IProcessObserver>();
1134    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1135
1136    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1137            = new ArrayList<ProcessChangeItem>();
1138    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1139            = new ArrayList<ProcessChangeItem>();
1140
1141    /**
1142     * Runtime CPU use collection thread.  This object's lock is used to
1143     * perform synchronization with the thread (notifying it to run).
1144     */
1145    final Thread mProcessCpuThread;
1146
1147    /**
1148     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1149     * Must acquire this object's lock when accessing it.
1150     * NOTE: this lock will be held while doing long operations (trawling
1151     * through all processes in /proc), so it should never be acquired by
1152     * any critical paths such as when holding the main activity manager lock.
1153     */
1154    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1155            MONITOR_THREAD_CPU_USAGE);
1156    final AtomicLong mLastCpuTime = new AtomicLong(0);
1157    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1158
1159    long mLastWriteTime = 0;
1160
1161    /**
1162     * Used to retain an update lock when the foreground activity is in
1163     * immersive mode.
1164     */
1165    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1166
1167    /**
1168     * Set to true after the system has finished booting.
1169     */
1170    boolean mBooted = false;
1171
1172    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1173    int mProcessLimitOverride = -1;
1174
1175    WindowManagerService mWindowManager;
1176
1177    final ActivityThread mSystemThread;
1178
1179    // Holds the current foreground user's id
1180    int mCurrentUserId = 0;
1181    // Holds the target user's id during a user switch
1182    int mTargetUserId = UserHandle.USER_NULL;
1183    // If there are multiple profiles for the current user, their ids are here
1184    // Currently only the primary user can have managed profiles
1185    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1186
1187    /**
1188     * Mapping from each known user ID to the profile group ID it is associated with.
1189     */
1190    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1191
1192    private UserManagerService mUserManager;
1193
1194    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1195        final ProcessRecord mApp;
1196        final int mPid;
1197        final IApplicationThread mAppThread;
1198
1199        AppDeathRecipient(ProcessRecord app, int pid,
1200                IApplicationThread thread) {
1201            if (localLOGV) Slog.v(
1202                TAG, "New death recipient " + this
1203                + " for thread " + thread.asBinder());
1204            mApp = app;
1205            mPid = pid;
1206            mAppThread = thread;
1207        }
1208
1209        @Override
1210        public void binderDied() {
1211            if (localLOGV) Slog.v(
1212                TAG, "Death received in " + this
1213                + " for thread " + mAppThread.asBinder());
1214            synchronized(ActivityManagerService.this) {
1215                appDiedLocked(mApp, mPid, mAppThread);
1216            }
1217        }
1218    }
1219
1220    static final int SHOW_ERROR_MSG = 1;
1221    static final int SHOW_NOT_RESPONDING_MSG = 2;
1222    static final int SHOW_FACTORY_ERROR_MSG = 3;
1223    static final int UPDATE_CONFIGURATION_MSG = 4;
1224    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1225    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1226    static final int SERVICE_TIMEOUT_MSG = 12;
1227    static final int UPDATE_TIME_ZONE = 13;
1228    static final int SHOW_UID_ERROR_MSG = 14;
1229    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1230    static final int PROC_START_TIMEOUT_MSG = 20;
1231    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1232    static final int KILL_APPLICATION_MSG = 22;
1233    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1234    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1235    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1236    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1237    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1238    static final int CLEAR_DNS_CACHE_MSG = 28;
1239    static final int UPDATE_HTTP_PROXY_MSG = 29;
1240    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1241    static final int DISPATCH_PROCESSES_CHANGED = 31;
1242    static final int DISPATCH_PROCESS_DIED = 32;
1243    static final int REPORT_MEM_USAGE_MSG = 33;
1244    static final int REPORT_USER_SWITCH_MSG = 34;
1245    static final int CONTINUE_USER_SWITCH_MSG = 35;
1246    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1247    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1248    static final int PERSIST_URI_GRANTS_MSG = 38;
1249    static final int REQUEST_ALL_PSS_MSG = 39;
1250    static final int START_PROFILES_MSG = 40;
1251    static final int UPDATE_TIME = 41;
1252    static final int SYSTEM_USER_START_MSG = 42;
1253    static final int SYSTEM_USER_CURRENT_MSG = 43;
1254    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1255    static final int FINISH_BOOTING_MSG = 45;
1256    static final int START_USER_SWITCH_MSG = 46;
1257    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1258    static final int DISMISS_DIALOG_MSG = 48;
1259    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1260    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1261
1262    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1263    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1264    static final int FIRST_COMPAT_MODE_MSG = 300;
1265    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1266
1267    CompatModeDialog mCompatModeDialog;
1268    long mLastMemUsageReportTime = 0;
1269
1270    /**
1271     * Flag whether the current user is a "monkey", i.e. whether
1272     * the UI is driven by a UI automation tool.
1273     */
1274    private boolean mUserIsMonkey;
1275
1276    /** Flag whether the device has a Recents UI */
1277    boolean mHasRecents;
1278
1279    /** The dimensions of the thumbnails in the Recents UI. */
1280    int mThumbnailWidth;
1281    int mThumbnailHeight;
1282
1283    final ServiceThread mHandlerThread;
1284    final MainHandler mHandler;
1285
1286    final class MainHandler extends Handler {
1287        public MainHandler(Looper looper) {
1288            super(looper, null, true);
1289        }
1290
1291        @Override
1292        public void handleMessage(Message msg) {
1293            switch (msg.what) {
1294            case SHOW_ERROR_MSG: {
1295                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1296                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1297                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1298                synchronized (ActivityManagerService.this) {
1299                    ProcessRecord proc = (ProcessRecord)data.get("app");
1300                    AppErrorResult res = (AppErrorResult) data.get("result");
1301                    if (proc != null && proc.crashDialog != null) {
1302                        Slog.e(TAG, "App already has crash dialog: " + proc);
1303                        if (res != null) {
1304                            res.set(0);
1305                        }
1306                        return;
1307                    }
1308                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1309                            >= Process.FIRST_APPLICATION_UID
1310                            && proc.pid != MY_PID);
1311                    for (int userId : mCurrentProfileIds) {
1312                        isBackground &= (proc.userId != userId);
1313                    }
1314                    if (isBackground && !showBackground) {
1315                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1316                        if (res != null) {
1317                            res.set(0);
1318                        }
1319                        return;
1320                    }
1321                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1322                        Dialog d = new AppErrorDialog(mContext,
1323                                ActivityManagerService.this, res, proc);
1324                        d.show();
1325                        proc.crashDialog = d;
1326                    } else {
1327                        // The device is asleep, so just pretend that the user
1328                        // saw a crash dialog and hit "force quit".
1329                        if (res != null) {
1330                            res.set(0);
1331                        }
1332                    }
1333                }
1334
1335                ensureBootCompleted();
1336            } break;
1337            case SHOW_NOT_RESPONDING_MSG: {
1338                synchronized (ActivityManagerService.this) {
1339                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1340                    ProcessRecord proc = (ProcessRecord)data.get("app");
1341                    if (proc != null && proc.anrDialog != null) {
1342                        Slog.e(TAG, "App already has anr dialog: " + proc);
1343                        return;
1344                    }
1345
1346                    Intent intent = new Intent("android.intent.action.ANR");
1347                    if (!mProcessesReady) {
1348                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1349                                | Intent.FLAG_RECEIVER_FOREGROUND);
1350                    }
1351                    broadcastIntentLocked(null, null, intent,
1352                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1353                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1354
1355                    if (mShowDialogs) {
1356                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1357                                mContext, proc, (ActivityRecord)data.get("activity"),
1358                                msg.arg1 != 0);
1359                        d.show();
1360                        proc.anrDialog = d;
1361                    } else {
1362                        // Just kill the app if there is no dialog to be shown.
1363                        killAppAtUsersRequest(proc, null);
1364                    }
1365                }
1366
1367                ensureBootCompleted();
1368            } break;
1369            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1370                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1371                synchronized (ActivityManagerService.this) {
1372                    ProcessRecord proc = (ProcessRecord) data.get("app");
1373                    if (proc == null) {
1374                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1375                        break;
1376                    }
1377                    if (proc.crashDialog != null) {
1378                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1379                        return;
1380                    }
1381                    AppErrorResult res = (AppErrorResult) data.get("result");
1382                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1383                        Dialog d = new StrictModeViolationDialog(mContext,
1384                                ActivityManagerService.this, res, proc);
1385                        d.show();
1386                        proc.crashDialog = d;
1387                    } else {
1388                        // The device is asleep, so just pretend that the user
1389                        // saw a crash dialog and hit "force quit".
1390                        res.set(0);
1391                    }
1392                }
1393                ensureBootCompleted();
1394            } break;
1395            case SHOW_FACTORY_ERROR_MSG: {
1396                Dialog d = new FactoryErrorDialog(
1397                    mContext, msg.getData().getCharSequence("msg"));
1398                d.show();
1399                ensureBootCompleted();
1400            } break;
1401            case UPDATE_CONFIGURATION_MSG: {
1402                final ContentResolver resolver = mContext.getContentResolver();
1403                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1404            } break;
1405            case GC_BACKGROUND_PROCESSES_MSG: {
1406                synchronized (ActivityManagerService.this) {
1407                    performAppGcsIfAppropriateLocked();
1408                }
1409            } break;
1410            case WAIT_FOR_DEBUGGER_MSG: {
1411                synchronized (ActivityManagerService.this) {
1412                    ProcessRecord app = (ProcessRecord)msg.obj;
1413                    if (msg.arg1 != 0) {
1414                        if (!app.waitedForDebugger) {
1415                            Dialog d = new AppWaitingForDebuggerDialog(
1416                                    ActivityManagerService.this,
1417                                    mContext, app);
1418                            app.waitDialog = d;
1419                            app.waitedForDebugger = true;
1420                            d.show();
1421                        }
1422                    } else {
1423                        if (app.waitDialog != null) {
1424                            app.waitDialog.dismiss();
1425                            app.waitDialog = null;
1426                        }
1427                    }
1428                }
1429            } break;
1430            case SERVICE_TIMEOUT_MSG: {
1431                if (mDidDexOpt) {
1432                    mDidDexOpt = false;
1433                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1434                    nmsg.obj = msg.obj;
1435                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1436                    return;
1437                }
1438                mServices.serviceTimeout((ProcessRecord)msg.obj);
1439            } break;
1440            case UPDATE_TIME_ZONE: {
1441                synchronized (ActivityManagerService.this) {
1442                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1443                        ProcessRecord r = mLruProcesses.get(i);
1444                        if (r.thread != null) {
1445                            try {
1446                                r.thread.updateTimeZone();
1447                            } catch (RemoteException ex) {
1448                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1449                            }
1450                        }
1451                    }
1452                }
1453            } break;
1454            case CLEAR_DNS_CACHE_MSG: {
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.clearDnsCache();
1461                            } catch (RemoteException ex) {
1462                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1463                            }
1464                        }
1465                    }
1466                }
1467            } break;
1468            case UPDATE_HTTP_PROXY_MSG: {
1469                ProxyInfo proxy = (ProxyInfo)msg.obj;
1470                String host = "";
1471                String port = "";
1472                String exclList = "";
1473                Uri pacFileUrl = Uri.EMPTY;
1474                if (proxy != null) {
1475                    host = proxy.getHost();
1476                    port = Integer.toString(proxy.getPort());
1477                    exclList = proxy.getExclusionListAsString();
1478                    pacFileUrl = proxy.getPacFileUrl();
1479                }
1480                synchronized (ActivityManagerService.this) {
1481                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1482                        ProcessRecord r = mLruProcesses.get(i);
1483                        if (r.thread != null) {
1484                            try {
1485                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1486                            } catch (RemoteException ex) {
1487                                Slog.w(TAG, "Failed to update http proxy for: " +
1488                                        r.info.processName);
1489                            }
1490                        }
1491                    }
1492                }
1493            } break;
1494            case SHOW_UID_ERROR_MSG: {
1495                if (mShowDialogs) {
1496                    AlertDialog d = new BaseErrorDialog(mContext);
1497                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1498                    d.setCancelable(false);
1499                    d.setTitle(mContext.getText(R.string.android_system_label));
1500                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1501                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1502                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1503                    d.show();
1504                }
1505            } break;
1506            case SHOW_FINGERPRINT_ERROR_MSG: {
1507                if (mShowDialogs) {
1508                    AlertDialog d = new BaseErrorDialog(mContext);
1509                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1510                    d.setCancelable(false);
1511                    d.setTitle(mContext.getText(R.string.android_system_label));
1512                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1513                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1514                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1515                    d.show();
1516                }
1517            } break;
1518            case PROC_START_TIMEOUT_MSG: {
1519                if (mDidDexOpt) {
1520                    mDidDexOpt = false;
1521                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1522                    nmsg.obj = msg.obj;
1523                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1524                    return;
1525                }
1526                ProcessRecord app = (ProcessRecord)msg.obj;
1527                synchronized (ActivityManagerService.this) {
1528                    processStartTimedOutLocked(app);
1529                }
1530            } break;
1531            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1532                synchronized (ActivityManagerService.this) {
1533                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1534                }
1535            } break;
1536            case KILL_APPLICATION_MSG: {
1537                synchronized (ActivityManagerService.this) {
1538                    int appid = msg.arg1;
1539                    boolean restart = (msg.arg2 == 1);
1540                    Bundle bundle = (Bundle)msg.obj;
1541                    String pkg = bundle.getString("pkg");
1542                    String reason = bundle.getString("reason");
1543                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1544                            false, UserHandle.USER_ALL, reason);
1545                }
1546            } break;
1547            case FINALIZE_PENDING_INTENT_MSG: {
1548                ((PendingIntentRecord)msg.obj).completeFinalize();
1549            } break;
1550            case POST_HEAVY_NOTIFICATION_MSG: {
1551                INotificationManager inm = NotificationManager.getService();
1552                if (inm == null) {
1553                    return;
1554                }
1555
1556                ActivityRecord root = (ActivityRecord)msg.obj;
1557                ProcessRecord process = root.app;
1558                if (process == null) {
1559                    return;
1560                }
1561
1562                try {
1563                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1564                    String text = mContext.getString(R.string.heavy_weight_notification,
1565                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1566                    Notification notification = new Notification();
1567                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1568                    notification.when = 0;
1569                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1570                    notification.tickerText = text;
1571                    notification.defaults = 0; // please be quiet
1572                    notification.sound = null;
1573                    notification.vibrate = null;
1574                    notification.color = mContext.getResources().getColor(
1575                            com.android.internal.R.color.system_notification_accent_color);
1576                    notification.setLatestEventInfo(context, text,
1577                            mContext.getText(R.string.heavy_weight_notification_detail),
1578                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1579                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1580                                    new UserHandle(root.userId)));
1581
1582                    try {
1583                        int[] outId = new int[1];
1584                        inm.enqueueNotificationWithTag("android", "android", null,
1585                                R.string.heavy_weight_notification,
1586                                notification, outId, root.userId);
1587                    } catch (RuntimeException e) {
1588                        Slog.w(ActivityManagerService.TAG,
1589                                "Error showing notification for heavy-weight app", e);
1590                    } catch (RemoteException e) {
1591                    }
1592                } catch (NameNotFoundException e) {
1593                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1594                }
1595            } break;
1596            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1597                INotificationManager inm = NotificationManager.getService();
1598                if (inm == null) {
1599                    return;
1600                }
1601                try {
1602                    inm.cancelNotificationWithTag("android", null,
1603                            R.string.heavy_weight_notification,  msg.arg1);
1604                } catch (RuntimeException e) {
1605                    Slog.w(ActivityManagerService.TAG,
1606                            "Error canceling notification for service", e);
1607                } catch (RemoteException e) {
1608                }
1609            } break;
1610            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1611                synchronized (ActivityManagerService.this) {
1612                    checkExcessivePowerUsageLocked(true);
1613                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1614                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1615                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1616                }
1617            } break;
1618            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1619                synchronized (ActivityManagerService.this) {
1620                    ActivityRecord ar = (ActivityRecord)msg.obj;
1621                    if (mCompatModeDialog != null) {
1622                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1623                                ar.info.applicationInfo.packageName)) {
1624                            return;
1625                        }
1626                        mCompatModeDialog.dismiss();
1627                        mCompatModeDialog = null;
1628                    }
1629                    if (ar != null && false) {
1630                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1631                                ar.packageName)) {
1632                            int mode = mCompatModePackages.computeCompatModeLocked(
1633                                    ar.info.applicationInfo);
1634                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1635                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1636                                mCompatModeDialog = new CompatModeDialog(
1637                                        ActivityManagerService.this, mContext,
1638                                        ar.info.applicationInfo);
1639                                mCompatModeDialog.show();
1640                            }
1641                        }
1642                    }
1643                }
1644                break;
1645            }
1646            case DISPATCH_PROCESSES_CHANGED: {
1647                dispatchProcessesChanged();
1648                break;
1649            }
1650            case DISPATCH_PROCESS_DIED: {
1651                final int pid = msg.arg1;
1652                final int uid = msg.arg2;
1653                dispatchProcessDied(pid, uid);
1654                break;
1655            }
1656            case REPORT_MEM_USAGE_MSG: {
1657                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1658                Thread thread = new Thread() {
1659                    @Override public void run() {
1660                        reportMemUsage(memInfos);
1661                    }
1662                };
1663                thread.start();
1664                break;
1665            }
1666            case START_USER_SWITCH_MSG: {
1667                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1668                break;
1669            }
1670            case REPORT_USER_SWITCH_MSG: {
1671                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1672                break;
1673            }
1674            case CONTINUE_USER_SWITCH_MSG: {
1675                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1676                break;
1677            }
1678            case USER_SWITCH_TIMEOUT_MSG: {
1679                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1680                break;
1681            }
1682            case IMMERSIVE_MODE_LOCK_MSG: {
1683                final boolean nextState = (msg.arg1 != 0);
1684                if (mUpdateLock.isHeld() != nextState) {
1685                    if (DEBUG_IMMERSIVE) {
1686                        final ActivityRecord r = (ActivityRecord) msg.obj;
1687                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1688                    }
1689                    if (nextState) {
1690                        mUpdateLock.acquire();
1691                    } else {
1692                        mUpdateLock.release();
1693                    }
1694                }
1695                break;
1696            }
1697            case PERSIST_URI_GRANTS_MSG: {
1698                writeGrantedUriPermissions();
1699                break;
1700            }
1701            case REQUEST_ALL_PSS_MSG: {
1702                synchronized (ActivityManagerService.this) {
1703                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1704                }
1705                break;
1706            }
1707            case START_PROFILES_MSG: {
1708                synchronized (ActivityManagerService.this) {
1709                    startProfilesLocked();
1710                }
1711                break;
1712            }
1713            case UPDATE_TIME: {
1714                synchronized (ActivityManagerService.this) {
1715                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1716                        ProcessRecord r = mLruProcesses.get(i);
1717                        if (r.thread != null) {
1718                            try {
1719                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1720                            } catch (RemoteException ex) {
1721                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1722                            }
1723                        }
1724                    }
1725                }
1726                break;
1727            }
1728            case SYSTEM_USER_START_MSG: {
1729                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1730                        Integer.toString(msg.arg1), msg.arg1);
1731                mSystemServiceManager.startUser(msg.arg1);
1732                break;
1733            }
1734            case SYSTEM_USER_CURRENT_MSG: {
1735                mBatteryStatsService.noteEvent(
1736                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1737                        Integer.toString(msg.arg2), msg.arg2);
1738                mBatteryStatsService.noteEvent(
1739                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1740                        Integer.toString(msg.arg1), msg.arg1);
1741                mSystemServiceManager.switchUser(msg.arg1);
1742                break;
1743            }
1744            case ENTER_ANIMATION_COMPLETE_MSG: {
1745                synchronized (ActivityManagerService.this) {
1746                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1747                    if (r != null && r.app != null && r.app.thread != null) {
1748                        try {
1749                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1750                        } catch (RemoteException e) {
1751                        }
1752                    }
1753                }
1754                break;
1755            }
1756            case FINISH_BOOTING_MSG: {
1757                if (msg.arg1 != 0) {
1758                    finishBooting();
1759                }
1760                if (msg.arg2 != 0) {
1761                    enableScreenAfterBoot();
1762                }
1763                break;
1764            }
1765            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1766                try {
1767                    Locale l = (Locale) msg.obj;
1768                    IBinder service = ServiceManager.getService("mount");
1769                    IMountService mountService = IMountService.Stub.asInterface(service);
1770                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1771                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1772                } catch (RemoteException e) {
1773                    Log.e(TAG, "Error storing locale for decryption UI", e);
1774                }
1775                break;
1776            }
1777            case DISMISS_DIALOG_MSG: {
1778                final Dialog d = (Dialog) msg.obj;
1779                d.dismiss();
1780                break;
1781            }
1782            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1783                synchronized (ActivityManagerService.this) {
1784                    int i = mTaskStackListeners.beginBroadcast();
1785                    while (i > 0) {
1786                        i--;
1787                        try {
1788                            // Make a one-way callback to the listener
1789                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1790                        } catch (RemoteException e){
1791                            // Handled by the RemoteCallbackList
1792                        }
1793                    }
1794                    mTaskStackListeners.finishBroadcast();
1795                }
1796                break;
1797            }
1798            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1799                final int uid = msg.arg1;
1800                final byte[] firstPacket = (byte[]) msg.obj;
1801
1802                synchronized (mPidsSelfLocked) {
1803                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1804                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1805                        if (p.uid == uid) {
1806                            try {
1807                                p.thread.notifyCleartextNetwork(firstPacket);
1808                            } catch (RemoteException ignored) {
1809                            }
1810                        }
1811                    }
1812                }
1813                break;
1814            }
1815            }
1816        }
1817    };
1818
1819    static final int COLLECT_PSS_BG_MSG = 1;
1820
1821    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1822        @Override
1823        public void handleMessage(Message msg) {
1824            switch (msg.what) {
1825            case COLLECT_PSS_BG_MSG: {
1826                long start = SystemClock.uptimeMillis();
1827                MemInfoReader memInfo = null;
1828                synchronized (ActivityManagerService.this) {
1829                    if (mFullPssPending) {
1830                        mFullPssPending = false;
1831                        memInfo = new MemInfoReader();
1832                    }
1833                }
1834                if (memInfo != null) {
1835                    updateCpuStatsNow();
1836                    long nativeTotalPss = 0;
1837                    synchronized (mProcessCpuTracker) {
1838                        final int N = mProcessCpuTracker.countStats();
1839                        for (int j=0; j<N; j++) {
1840                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1841                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1842                                // This is definitely an application process; skip it.
1843                                continue;
1844                            }
1845                            synchronized (mPidsSelfLocked) {
1846                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1847                                    // This is one of our own processes; skip it.
1848                                    continue;
1849                                }
1850                            }
1851                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1852                        }
1853                    }
1854                    memInfo.readMemInfo();
1855                    synchronized (ActivityManagerService.this) {
1856                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1857                                + (SystemClock.uptimeMillis()-start) + "ms");
1858                        final long cachedKb = memInfo.getCachedSizeKb();
1859                        final long freeKb = memInfo.getFreeSizeKb();
1860                        final long zramKb = memInfo.getZramTotalSizeKb();
1861                        final long kernelKb = memInfo.getKernelUsedSizeKb();
1862                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
1863                                kernelKb*1024, nativeTotalPss*1024);
1864                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
1865                                nativeTotalPss);
1866                    }
1867                }
1868
1869                int num = 0;
1870                long[] tmp = new long[1];
1871                do {
1872                    ProcessRecord proc;
1873                    int procState;
1874                    int pid;
1875                    long lastPssTime;
1876                    synchronized (ActivityManagerService.this) {
1877                        if (mPendingPssProcesses.size() <= 0) {
1878                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1879                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1880                            mPendingPssProcesses.clear();
1881                            return;
1882                        }
1883                        proc = mPendingPssProcesses.remove(0);
1884                        procState = proc.pssProcState;
1885                        lastPssTime = proc.lastPssTime;
1886                        if (proc.thread != null && procState == proc.setProcState
1887                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1888                                        < SystemClock.uptimeMillis()) {
1889                            pid = proc.pid;
1890                        } else {
1891                            proc = null;
1892                            pid = 0;
1893                        }
1894                    }
1895                    if (proc != null) {
1896                        long pss = Debug.getPss(pid, tmp, null);
1897                        synchronized (ActivityManagerService.this) {
1898                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1899                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1900                                num++;
1901                                recordPssSample(proc, procState, pss, tmp[0],
1902                                        SystemClock.uptimeMillis());
1903                            }
1904                        }
1905                    }
1906                } while (true);
1907            }
1908            }
1909        }
1910    };
1911
1912    public void setSystemProcess() {
1913        try {
1914            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1915            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1916            ServiceManager.addService("meminfo", new MemBinder(this));
1917            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1918            ServiceManager.addService("dbinfo", new DbBinder(this));
1919            if (MONITOR_CPU_USAGE) {
1920                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1921            }
1922            ServiceManager.addService("permission", new PermissionController(this));
1923
1924            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1925                    "android", STOCK_PM_FLAGS);
1926            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1927
1928            synchronized (this) {
1929                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1930                app.persistent = true;
1931                app.pid = MY_PID;
1932                app.maxAdj = ProcessList.SYSTEM_ADJ;
1933                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1934                mProcessNames.put(app.processName, app.uid, app);
1935                synchronized (mPidsSelfLocked) {
1936                    mPidsSelfLocked.put(app.pid, app);
1937                }
1938                updateLruProcessLocked(app, false, null);
1939                updateOomAdjLocked();
1940            }
1941        } catch (PackageManager.NameNotFoundException e) {
1942            throw new RuntimeException(
1943                    "Unable to find android system package", e);
1944        }
1945    }
1946
1947    public void setWindowManager(WindowManagerService wm) {
1948        mWindowManager = wm;
1949        mStackSupervisor.setWindowManager(wm);
1950    }
1951
1952    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1953        mUsageStatsService = usageStatsManager;
1954    }
1955
1956    public void startObservingNativeCrashes() {
1957        final NativeCrashListener ncl = new NativeCrashListener(this);
1958        ncl.start();
1959    }
1960
1961    public IAppOpsService getAppOpsService() {
1962        return mAppOpsService;
1963    }
1964
1965    static class MemBinder extends Binder {
1966        ActivityManagerService mActivityManagerService;
1967        MemBinder(ActivityManagerService activityManagerService) {
1968            mActivityManagerService = activityManagerService;
1969        }
1970
1971        @Override
1972        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1973            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1974                    != PackageManager.PERMISSION_GRANTED) {
1975                pw.println("Permission Denial: can't dump meminfo from from pid="
1976                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1977                        + " without permission " + android.Manifest.permission.DUMP);
1978                return;
1979            }
1980
1981            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1982        }
1983    }
1984
1985    static class GraphicsBinder extends Binder {
1986        ActivityManagerService mActivityManagerService;
1987        GraphicsBinder(ActivityManagerService activityManagerService) {
1988            mActivityManagerService = activityManagerService;
1989        }
1990
1991        @Override
1992        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1993            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1994                    != PackageManager.PERMISSION_GRANTED) {
1995                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1996                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1997                        + " without permission " + android.Manifest.permission.DUMP);
1998                return;
1999            }
2000
2001            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2002        }
2003    }
2004
2005    static class DbBinder extends Binder {
2006        ActivityManagerService mActivityManagerService;
2007        DbBinder(ActivityManagerService activityManagerService) {
2008            mActivityManagerService = activityManagerService;
2009        }
2010
2011        @Override
2012        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2013            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2014                    != PackageManager.PERMISSION_GRANTED) {
2015                pw.println("Permission Denial: can't dump dbinfo from from pid="
2016                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2017                        + " without permission " + android.Manifest.permission.DUMP);
2018                return;
2019            }
2020
2021            mActivityManagerService.dumpDbInfo(fd, pw, args);
2022        }
2023    }
2024
2025    static class CpuBinder extends Binder {
2026        ActivityManagerService mActivityManagerService;
2027        CpuBinder(ActivityManagerService activityManagerService) {
2028            mActivityManagerService = activityManagerService;
2029        }
2030
2031        @Override
2032        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2033            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2034                    != PackageManager.PERMISSION_GRANTED) {
2035                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2036                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2037                        + " without permission " + android.Manifest.permission.DUMP);
2038                return;
2039            }
2040
2041            synchronized (mActivityManagerService.mProcessCpuTracker) {
2042                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2043                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2044                        SystemClock.uptimeMillis()));
2045            }
2046        }
2047    }
2048
2049    public static final class Lifecycle extends SystemService {
2050        private final ActivityManagerService mService;
2051
2052        public Lifecycle(Context context) {
2053            super(context);
2054            mService = new ActivityManagerService(context);
2055        }
2056
2057        @Override
2058        public void onStart() {
2059            mService.start();
2060        }
2061
2062        public ActivityManagerService getService() {
2063            return mService;
2064        }
2065    }
2066
2067    // Note: This method is invoked on the main thread but may need to attach various
2068    // handlers to other threads.  So take care to be explicit about the looper.
2069    public ActivityManagerService(Context systemContext) {
2070        mContext = systemContext;
2071        mFactoryTest = FactoryTest.getMode();
2072        mSystemThread = ActivityThread.currentActivityThread();
2073
2074        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2075
2076        mHandlerThread = new ServiceThread(TAG,
2077                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2078        mHandlerThread.start();
2079        mHandler = new MainHandler(mHandlerThread.getLooper());
2080
2081        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2082                "foreground", BROADCAST_FG_TIMEOUT, false);
2083        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2084                "background", BROADCAST_BG_TIMEOUT, true);
2085        mBroadcastQueues[0] = mFgBroadcastQueue;
2086        mBroadcastQueues[1] = mBgBroadcastQueue;
2087
2088        mServices = new ActiveServices(this);
2089        mProviderMap = new ProviderMap(this);
2090
2091        // TODO: Move creation of battery stats service outside of activity manager service.
2092        File dataDir = Environment.getDataDirectory();
2093        File systemDir = new File(dataDir, "system");
2094        systemDir.mkdirs();
2095        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2096        mBatteryStatsService.getActiveStatistics().readLocked();
2097        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2098        mOnBattery = DEBUG_POWER ? true
2099                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2100        mBatteryStatsService.getActiveStatistics().setCallback(this);
2101
2102        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2103
2104        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2105
2106        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2107
2108        // User 0 is the first and only user that runs at boot.
2109        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2110        mUserLru.add(Integer.valueOf(0));
2111        updateStartedUserArrayLocked();
2112
2113        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2114            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2115
2116        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2117
2118        mConfiguration.setToDefaults();
2119        mConfiguration.locale = Locale.getDefault();
2120
2121        mConfigurationSeq = mConfiguration.seq = 1;
2122        mProcessCpuTracker.init();
2123
2124        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2125        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2126        mRecentTasks = new RecentTasks(this);
2127        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2128        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2129
2130        mProcessCpuThread = new Thread("CpuTracker") {
2131            @Override
2132            public void run() {
2133                while (true) {
2134                    try {
2135                        try {
2136                            synchronized(this) {
2137                                final long now = SystemClock.uptimeMillis();
2138                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2139                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2140                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2141                                //        + ", write delay=" + nextWriteDelay);
2142                                if (nextWriteDelay < nextCpuDelay) {
2143                                    nextCpuDelay = nextWriteDelay;
2144                                }
2145                                if (nextCpuDelay > 0) {
2146                                    mProcessCpuMutexFree.set(true);
2147                                    this.wait(nextCpuDelay);
2148                                }
2149                            }
2150                        } catch (InterruptedException e) {
2151                        }
2152                        updateCpuStatsNow();
2153                    } catch (Exception e) {
2154                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2155                    }
2156                }
2157            }
2158        };
2159
2160        Watchdog.getInstance().addMonitor(this);
2161        Watchdog.getInstance().addThread(mHandler);
2162    }
2163
2164    public void setSystemServiceManager(SystemServiceManager mgr) {
2165        mSystemServiceManager = mgr;
2166    }
2167
2168    public void setInstaller(Installer installer) {
2169        mInstaller = installer;
2170    }
2171
2172    private void start() {
2173        Process.removeAllProcessGroups();
2174        mProcessCpuThread.start();
2175
2176        mBatteryStatsService.publish(mContext);
2177        mAppOpsService.publish(mContext);
2178        Slog.d("AppOps", "AppOpsService published");
2179        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2180    }
2181
2182    public void initPowerManagement() {
2183        mStackSupervisor.initPowerManagement();
2184        mBatteryStatsService.initPowerManagement();
2185    }
2186
2187    @Override
2188    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2189            throws RemoteException {
2190        if (code == SYSPROPS_TRANSACTION) {
2191            // We need to tell all apps about the system property change.
2192            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2193            synchronized(this) {
2194                final int NP = mProcessNames.getMap().size();
2195                for (int ip=0; ip<NP; ip++) {
2196                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2197                    final int NA = apps.size();
2198                    for (int ia=0; ia<NA; ia++) {
2199                        ProcessRecord app = apps.valueAt(ia);
2200                        if (app.thread != null) {
2201                            procs.add(app.thread.asBinder());
2202                        }
2203                    }
2204                }
2205            }
2206
2207            int N = procs.size();
2208            for (int i=0; i<N; i++) {
2209                Parcel data2 = Parcel.obtain();
2210                try {
2211                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2212                } catch (RemoteException e) {
2213                }
2214                data2.recycle();
2215            }
2216        }
2217        try {
2218            return super.onTransact(code, data, reply, flags);
2219        } catch (RuntimeException e) {
2220            // The activity manager only throws security exceptions, so let's
2221            // log all others.
2222            if (!(e instanceof SecurityException)) {
2223                Slog.wtf(TAG, "Activity Manager Crash", e);
2224            }
2225            throw e;
2226        }
2227    }
2228
2229    void updateCpuStats() {
2230        final long now = SystemClock.uptimeMillis();
2231        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2232            return;
2233        }
2234        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2235            synchronized (mProcessCpuThread) {
2236                mProcessCpuThread.notify();
2237            }
2238        }
2239    }
2240
2241    void updateCpuStatsNow() {
2242        synchronized (mProcessCpuTracker) {
2243            mProcessCpuMutexFree.set(false);
2244            final long now = SystemClock.uptimeMillis();
2245            boolean haveNewCpuStats = false;
2246
2247            if (MONITOR_CPU_USAGE &&
2248                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2249                mLastCpuTime.set(now);
2250                haveNewCpuStats = true;
2251                mProcessCpuTracker.update();
2252                //Slog.i(TAG, mProcessCpu.printCurrentState());
2253                //Slog.i(TAG, "Total CPU usage: "
2254                //        + mProcessCpu.getTotalCpuPercent() + "%");
2255
2256                // Slog the cpu usage if the property is set.
2257                if ("true".equals(SystemProperties.get("events.cpu"))) {
2258                    int user = mProcessCpuTracker.getLastUserTime();
2259                    int system = mProcessCpuTracker.getLastSystemTime();
2260                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2261                    int irq = mProcessCpuTracker.getLastIrqTime();
2262                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2263                    int idle = mProcessCpuTracker.getLastIdleTime();
2264
2265                    int total = user + system + iowait + irq + softIrq + idle;
2266                    if (total == 0) total = 1;
2267
2268                    EventLog.writeEvent(EventLogTags.CPU,
2269                            ((user+system+iowait+irq+softIrq) * 100) / total,
2270                            (user * 100) / total,
2271                            (system * 100) / total,
2272                            (iowait * 100) / total,
2273                            (irq * 100) / total,
2274                            (softIrq * 100) / total);
2275                }
2276            }
2277
2278            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2279            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2280            synchronized(bstats) {
2281                synchronized(mPidsSelfLocked) {
2282                    if (haveNewCpuStats) {
2283                        if (mOnBattery) {
2284                            int perc = bstats.startAddingCpuLocked();
2285                            int totalUTime = 0;
2286                            int totalSTime = 0;
2287                            final int N = mProcessCpuTracker.countStats();
2288                            for (int i=0; i<N; i++) {
2289                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2290                                if (!st.working) {
2291                                    continue;
2292                                }
2293                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2294                                int otherUTime = (st.rel_utime*perc)/100;
2295                                int otherSTime = (st.rel_stime*perc)/100;
2296                                totalUTime += otherUTime;
2297                                totalSTime += otherSTime;
2298                                if (pr != null) {
2299                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2300                                    if (ps == null || !ps.isActive()) {
2301                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2302                                                pr.info.uid, pr.processName);
2303                                    }
2304                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2305                                            st.rel_stime-otherSTime);
2306                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2307                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2308                                } else {
2309                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2310                                    if (ps == null || !ps.isActive()) {
2311                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2312                                                bstats.mapUid(st.uid), st.name);
2313                                    }
2314                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2315                                            st.rel_stime-otherSTime);
2316                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2317                                }
2318                            }
2319                            bstats.finishAddingCpuLocked(perc, totalUTime,
2320                                    totalSTime, cpuSpeedTimes);
2321                        }
2322                    }
2323                }
2324
2325                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2326                    mLastWriteTime = now;
2327                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2328                }
2329            }
2330        }
2331    }
2332
2333    @Override
2334    public void batteryNeedsCpuUpdate() {
2335        updateCpuStatsNow();
2336    }
2337
2338    @Override
2339    public void batteryPowerChanged(boolean onBattery) {
2340        // When plugging in, update the CPU stats first before changing
2341        // the plug state.
2342        updateCpuStatsNow();
2343        synchronized (this) {
2344            synchronized(mPidsSelfLocked) {
2345                mOnBattery = DEBUG_POWER ? true : onBattery;
2346            }
2347        }
2348    }
2349
2350    /**
2351     * Initialize the application bind args. These are passed to each
2352     * process when the bindApplication() IPC is sent to the process. They're
2353     * lazily setup to make sure the services are running when they're asked for.
2354     */
2355    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2356        if (mAppBindArgs == null) {
2357            mAppBindArgs = new HashMap<>();
2358
2359            // Isolated processes won't get this optimization, so that we don't
2360            // violate the rules about which services they have access to.
2361            if (!isolated) {
2362                // Setup the application init args
2363                mAppBindArgs.put("package", ServiceManager.getService("package"));
2364                mAppBindArgs.put("window", ServiceManager.getService("window"));
2365                mAppBindArgs.put(Context.ALARM_SERVICE,
2366                        ServiceManager.getService(Context.ALARM_SERVICE));
2367            }
2368        }
2369        return mAppBindArgs;
2370    }
2371
2372    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2373        if (mFocusedActivity != r) {
2374            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2375            mFocusedActivity = r;
2376            if (r.task != null && r.task.voiceInteractor != null) {
2377                startRunningVoiceLocked();
2378            } else {
2379                finishRunningVoiceLocked();
2380            }
2381            mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity");
2382            if (r != null) {
2383                mWindowManager.setFocusedApp(r.appToken, true);
2384            }
2385            applyUpdateLockStateLocked(r);
2386        }
2387        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
2388                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2389    }
2390
2391    final void clearFocusedActivity(ActivityRecord r) {
2392        if (mFocusedActivity == r) {
2393            mFocusedActivity = null;
2394        }
2395    }
2396
2397    @Override
2398    public void setFocusedStack(int stackId) {
2399        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2400        synchronized (ActivityManagerService.this) {
2401            ActivityStack stack = mStackSupervisor.getStack(stackId);
2402            if (stack != null) {
2403                ActivityRecord r = stack.topRunningActivityLocked(null);
2404                if (r != null) {
2405                    setFocusedActivityLocked(r, "setFocusedStack");
2406                }
2407            }
2408        }
2409    }
2410
2411    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2412    @Override
2413    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2414        synchronized (ActivityManagerService.this) {
2415            if (listener != null) {
2416                mTaskStackListeners.register(listener);
2417            }
2418        }
2419    }
2420
2421    @Override
2422    public void notifyActivityDrawn(IBinder token) {
2423        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2424        synchronized (this) {
2425            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2426            if (r != null) {
2427                r.task.stack.notifyActivityDrawnLocked(r);
2428            }
2429        }
2430    }
2431
2432    final void applyUpdateLockStateLocked(ActivityRecord r) {
2433        // Modifications to the UpdateLock state are done on our handler, outside
2434        // the activity manager's locks.  The new state is determined based on the
2435        // state *now* of the relevant activity record.  The object is passed to
2436        // the handler solely for logging detail, not to be consulted/modified.
2437        final boolean nextState = r != null && r.immersive;
2438        mHandler.sendMessage(
2439                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2440    }
2441
2442    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2443        Message msg = Message.obtain();
2444        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2445        msg.obj = r.task.askedCompatMode ? null : r;
2446        mHandler.sendMessage(msg);
2447    }
2448
2449    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2450            String what, Object obj, ProcessRecord srcApp) {
2451        app.lastActivityTime = now;
2452
2453        if (app.activities.size() > 0) {
2454            // Don't want to touch dependent processes that are hosting activities.
2455            return index;
2456        }
2457
2458        int lrui = mLruProcesses.lastIndexOf(app);
2459        if (lrui < 0) {
2460            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2461                    + what + " " + obj + " from " + srcApp);
2462            return index;
2463        }
2464
2465        if (lrui >= index) {
2466            // Don't want to cause this to move dependent processes *back* in the
2467            // list as if they were less frequently used.
2468            return index;
2469        }
2470
2471        if (lrui >= mLruProcessActivityStart) {
2472            // Don't want to touch dependent processes that are hosting activities.
2473            return index;
2474        }
2475
2476        mLruProcesses.remove(lrui);
2477        if (index > 0) {
2478            index--;
2479        }
2480        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2481                + " in LRU list: " + app);
2482        mLruProcesses.add(index, app);
2483        return index;
2484    }
2485
2486    final void removeLruProcessLocked(ProcessRecord app) {
2487        int lrui = mLruProcesses.lastIndexOf(app);
2488        if (lrui >= 0) {
2489            if (!app.killed) {
2490                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2491                Process.killProcessQuiet(app.pid);
2492                Process.killProcessGroup(app.info.uid, app.pid);
2493            }
2494            if (lrui <= mLruProcessActivityStart) {
2495                mLruProcessActivityStart--;
2496            }
2497            if (lrui <= mLruProcessServiceStart) {
2498                mLruProcessServiceStart--;
2499            }
2500            mLruProcesses.remove(lrui);
2501        }
2502    }
2503
2504    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2505            ProcessRecord client) {
2506        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2507                || app.treatLikeActivity;
2508        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2509        if (!activityChange && hasActivity) {
2510            // The process has activities, so we are only allowing activity-based adjustments
2511            // to move it.  It should be kept in the front of the list with other
2512            // processes that have activities, and we don't want those to change their
2513            // order except due to activity operations.
2514            return;
2515        }
2516
2517        mLruSeq++;
2518        final long now = SystemClock.uptimeMillis();
2519        app.lastActivityTime = now;
2520
2521        // First a quick reject: if the app is already at the position we will
2522        // put it, then there is nothing to do.
2523        if (hasActivity) {
2524            final int N = mLruProcesses.size();
2525            if (N > 0 && mLruProcesses.get(N-1) == app) {
2526                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2527                return;
2528            }
2529        } else {
2530            if (mLruProcessServiceStart > 0
2531                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2532                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2533                return;
2534            }
2535        }
2536
2537        int lrui = mLruProcesses.lastIndexOf(app);
2538
2539        if (app.persistent && lrui >= 0) {
2540            // We don't care about the position of persistent processes, as long as
2541            // they are in the list.
2542            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2543            return;
2544        }
2545
2546        /* In progress: compute new position first, so we can avoid doing work
2547           if the process is not actually going to move.  Not yet working.
2548        int addIndex;
2549        int nextIndex;
2550        boolean inActivity = false, inService = false;
2551        if (hasActivity) {
2552            // Process has activities, put it at the very tipsy-top.
2553            addIndex = mLruProcesses.size();
2554            nextIndex = mLruProcessServiceStart;
2555            inActivity = true;
2556        } else if (hasService) {
2557            // Process has services, put it at the top of the service list.
2558            addIndex = mLruProcessActivityStart;
2559            nextIndex = mLruProcessServiceStart;
2560            inActivity = true;
2561            inService = true;
2562        } else  {
2563            // Process not otherwise of interest, it goes to the top of the non-service area.
2564            addIndex = mLruProcessServiceStart;
2565            if (client != null) {
2566                int clientIndex = mLruProcesses.lastIndexOf(client);
2567                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2568                        + app);
2569                if (clientIndex >= 0 && addIndex > clientIndex) {
2570                    addIndex = clientIndex;
2571                }
2572            }
2573            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2574        }
2575
2576        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2577                + mLruProcessActivityStart + "): " + app);
2578        */
2579
2580        if (lrui >= 0) {
2581            if (lrui < mLruProcessActivityStart) {
2582                mLruProcessActivityStart--;
2583            }
2584            if (lrui < mLruProcessServiceStart) {
2585                mLruProcessServiceStart--;
2586            }
2587            /*
2588            if (addIndex > lrui) {
2589                addIndex--;
2590            }
2591            if (nextIndex > lrui) {
2592                nextIndex--;
2593            }
2594            */
2595            mLruProcesses.remove(lrui);
2596        }
2597
2598        /*
2599        mLruProcesses.add(addIndex, app);
2600        if (inActivity) {
2601            mLruProcessActivityStart++;
2602        }
2603        if (inService) {
2604            mLruProcessActivityStart++;
2605        }
2606        */
2607
2608        int nextIndex;
2609        if (hasActivity) {
2610            final int N = mLruProcesses.size();
2611            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2612                // Process doesn't have activities, but has clients with
2613                // activities...  move it up, but one below the top (the top
2614                // should always have a real activity).
2615                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2616                mLruProcesses.add(N-1, app);
2617                // To keep it from spamming the LRU list (by making a bunch of clients),
2618                // we will push down any other entries owned by the app.
2619                final int uid = app.info.uid;
2620                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2621                    ProcessRecord subProc = mLruProcesses.get(i);
2622                    if (subProc.info.uid == uid) {
2623                        // We want to push this one down the list.  If the process after
2624                        // it is for the same uid, however, don't do so, because we don't
2625                        // want them internally to be re-ordered.
2626                        if (mLruProcesses.get(i-1).info.uid != uid) {
2627                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2628                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2629                            ProcessRecord tmp = mLruProcesses.get(i);
2630                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2631                            mLruProcesses.set(i-1, tmp);
2632                            i--;
2633                        }
2634                    } else {
2635                        // A gap, we can stop here.
2636                        break;
2637                    }
2638                }
2639            } else {
2640                // Process has activities, put it at the very tipsy-top.
2641                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2642                mLruProcesses.add(app);
2643            }
2644            nextIndex = mLruProcessServiceStart;
2645        } else if (hasService) {
2646            // Process has services, put it at the top of the service list.
2647            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2648            mLruProcesses.add(mLruProcessActivityStart, app);
2649            nextIndex = mLruProcessServiceStart;
2650            mLruProcessActivityStart++;
2651        } else  {
2652            // Process not otherwise of interest, it goes to the top of the non-service area.
2653            int index = mLruProcessServiceStart;
2654            if (client != null) {
2655                // If there is a client, don't allow the process to be moved up higher
2656                // in the list than that client.
2657                int clientIndex = mLruProcesses.lastIndexOf(client);
2658                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2659                        + " when updating " + app);
2660                if (clientIndex <= lrui) {
2661                    // Don't allow the client index restriction to push it down farther in the
2662                    // list than it already is.
2663                    clientIndex = lrui;
2664                }
2665                if (clientIndex >= 0 && index > clientIndex) {
2666                    index = clientIndex;
2667                }
2668            }
2669            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2670            mLruProcesses.add(index, app);
2671            nextIndex = index-1;
2672            mLruProcessActivityStart++;
2673            mLruProcessServiceStart++;
2674        }
2675
2676        // If the app is currently using a content provider or service,
2677        // bump those processes as well.
2678        for (int j=app.connections.size()-1; j>=0; j--) {
2679            ConnectionRecord cr = app.connections.valueAt(j);
2680            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2681                    && cr.binding.service.app != null
2682                    && cr.binding.service.app.lruSeq != mLruSeq
2683                    && !cr.binding.service.app.persistent) {
2684                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2685                        "service connection", cr, app);
2686            }
2687        }
2688        for (int j=app.conProviders.size()-1; j>=0; j--) {
2689            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2690            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2691                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2692                        "provider reference", cpr, app);
2693            }
2694        }
2695    }
2696
2697    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2698        if (uid == Process.SYSTEM_UID) {
2699            // The system gets to run in any process.  If there are multiple
2700            // processes with the same uid, just pick the first (this
2701            // should never happen).
2702            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2703            if (procs == null) return null;
2704            final int N = procs.size();
2705            for (int i = 0; i < N; i++) {
2706                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2707            }
2708        }
2709        ProcessRecord proc = mProcessNames.get(processName, uid);
2710        if (false && proc != null && !keepIfLarge
2711                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2712                && proc.lastCachedPss >= 4000) {
2713            // Turn this condition on to cause killing to happen regularly, for testing.
2714            if (proc.baseProcessTracker != null) {
2715                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2716            }
2717            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2718        } else if (proc != null && !keepIfLarge
2719                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2720                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2721            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2722            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2723                if (proc.baseProcessTracker != null) {
2724                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2725                }
2726                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2727            }
2728        }
2729        return proc;
2730    }
2731
2732    void ensurePackageDexOpt(String packageName) {
2733        IPackageManager pm = AppGlobals.getPackageManager();
2734        try {
2735            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2736                mDidDexOpt = true;
2737            }
2738        } catch (RemoteException e) {
2739        }
2740    }
2741
2742    boolean isNextTransitionForward() {
2743        int transit = mWindowManager.getPendingAppTransition();
2744        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2745                || transit == AppTransition.TRANSIT_TASK_OPEN
2746                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2747    }
2748
2749    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2750            String processName, String abiOverride, int uid, Runnable crashHandler) {
2751        synchronized(this) {
2752            ApplicationInfo info = new ApplicationInfo();
2753            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2754            // For isolated processes, the former contains the parent's uid and the latter the
2755            // actual uid of the isolated process.
2756            // In the special case introduced by this method (which is, starting an isolated
2757            // process directly from the SystemServer without an actual parent app process) the
2758            // closest thing to a parent's uid is SYSTEM_UID.
2759            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2760            // the |isolated| logic in the ProcessRecord constructor.
2761            info.uid = Process.SYSTEM_UID;
2762            info.processName = processName;
2763            info.className = entryPoint;
2764            info.packageName = "android";
2765            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2766                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2767                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2768                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2769                    crashHandler);
2770            return proc != null ? proc.pid : 0;
2771        }
2772    }
2773
2774    final ProcessRecord startProcessLocked(String processName,
2775            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2776            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2777            boolean isolated, boolean keepIfLarge) {
2778        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2779                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2780                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2781                null /* crashHandler */);
2782    }
2783
2784    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2785            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2786            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2787            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2788        long startTime = SystemClock.elapsedRealtime();
2789        ProcessRecord app;
2790        if (!isolated) {
2791            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2792            checkTime(startTime, "startProcess: after getProcessRecord");
2793        } else {
2794            // If this is an isolated process, it can't re-use an existing process.
2795            app = null;
2796        }
2797        // We don't have to do anything more if:
2798        // (1) There is an existing application record; and
2799        // (2) The caller doesn't think it is dead, OR there is no thread
2800        //     object attached to it so we know it couldn't have crashed; and
2801        // (3) There is a pid assigned to it, so it is either starting or
2802        //     already running.
2803        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2804                + " app=" + app + " knownToBeDead=" + knownToBeDead
2805                + " thread=" + (app != null ? app.thread : null)
2806                + " pid=" + (app != null ? app.pid : -1));
2807        if (app != null && app.pid > 0) {
2808            if (!knownToBeDead || app.thread == null) {
2809                // We already have the app running, or are waiting for it to
2810                // come up (we have a pid but not yet its thread), so keep it.
2811                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2812                // If this is a new package in the process, add the package to the list
2813                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2814                checkTime(startTime, "startProcess: done, added package to proc");
2815                return app;
2816            }
2817
2818            // An application record is attached to a previous process,
2819            // clean it up now.
2820            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2821            checkTime(startTime, "startProcess: bad proc running, killing");
2822            Process.killProcessGroup(app.info.uid, app.pid);
2823            handleAppDiedLocked(app, true, true);
2824            checkTime(startTime, "startProcess: done killing old proc");
2825        }
2826
2827        String hostingNameStr = hostingName != null
2828                ? hostingName.flattenToShortString() : null;
2829
2830        if (!isolated) {
2831            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2832                // If we are in the background, then check to see if this process
2833                // is bad.  If so, we will just silently fail.
2834                if (mBadProcesses.get(info.processName, info.uid) != null) {
2835                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2836                            + "/" + info.processName);
2837                    return null;
2838                }
2839            } else {
2840                // When the user is explicitly starting a process, then clear its
2841                // crash count so that we won't make it bad until they see at
2842                // least one crash dialog again, and make the process good again
2843                // if it had been bad.
2844                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2845                        + "/" + info.processName);
2846                mProcessCrashTimes.remove(info.processName, info.uid);
2847                if (mBadProcesses.get(info.processName, info.uid) != null) {
2848                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2849                            UserHandle.getUserId(info.uid), info.uid,
2850                            info.processName);
2851                    mBadProcesses.remove(info.processName, info.uid);
2852                    if (app != null) {
2853                        app.bad = false;
2854                    }
2855                }
2856            }
2857        }
2858
2859        if (app == null) {
2860            checkTime(startTime, "startProcess: creating new process record");
2861            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2862            if (app == null) {
2863                Slog.w(TAG, "Failed making new process record for "
2864                        + processName + "/" + info.uid + " isolated=" + isolated);
2865                return null;
2866            }
2867            app.crashHandler = crashHandler;
2868            mProcessNames.put(processName, app.uid, app);
2869            if (isolated) {
2870                mIsolatedProcesses.put(app.uid, app);
2871            }
2872            checkTime(startTime, "startProcess: done creating new process record");
2873        } else {
2874            // If this is a new package in the process, add the package to the list
2875            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2876            checkTime(startTime, "startProcess: added package to existing proc");
2877        }
2878
2879        // If the system is not ready yet, then hold off on starting this
2880        // process until it is.
2881        if (!mProcessesReady
2882                && !isAllowedWhileBooting(info)
2883                && !allowWhileBooting) {
2884            if (!mProcessesOnHold.contains(app)) {
2885                mProcessesOnHold.add(app);
2886            }
2887            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2888            checkTime(startTime, "startProcess: returning with proc on hold");
2889            return app;
2890        }
2891
2892        checkTime(startTime, "startProcess: stepping in to startProcess");
2893        startProcessLocked(
2894                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2895        checkTime(startTime, "startProcess: done starting proc!");
2896        return (app.pid != 0) ? app : null;
2897    }
2898
2899    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2900        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2901    }
2902
2903    private final void startProcessLocked(ProcessRecord app,
2904            String hostingType, String hostingNameStr) {
2905        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2906                null /* entryPoint */, null /* entryPointArgs */);
2907    }
2908
2909    private final void startProcessLocked(ProcessRecord app, String hostingType,
2910            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2911        long startTime = SystemClock.elapsedRealtime();
2912        if (app.pid > 0 && app.pid != MY_PID) {
2913            checkTime(startTime, "startProcess: removing from pids map");
2914            synchronized (mPidsSelfLocked) {
2915                mPidsSelfLocked.remove(app.pid);
2916                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2917            }
2918            checkTime(startTime, "startProcess: done removing from pids map");
2919            app.setPid(0);
2920        }
2921
2922        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2923                "startProcessLocked removing on hold: " + app);
2924        mProcessesOnHold.remove(app);
2925
2926        checkTime(startTime, "startProcess: starting to update cpu stats");
2927        updateCpuStats();
2928        checkTime(startTime, "startProcess: done updating cpu stats");
2929
2930        try {
2931            int uid = app.uid;
2932
2933            int[] gids = null;
2934            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2935            if (!app.isolated) {
2936                int[] permGids = null;
2937                try {
2938                    checkTime(startTime, "startProcess: getting gids from package manager");
2939                    final PackageManager pm = mContext.getPackageManager();
2940                    permGids = pm.getPackageGids(app.info.packageName);
2941
2942                    if (Environment.isExternalStorageEmulated()) {
2943                        checkTime(startTime, "startProcess: checking external storage perm");
2944                        if (pm.checkPermission(
2945                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2946                                app.info.packageName) == PERMISSION_GRANTED) {
2947                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2948                        } else {
2949                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2950                        }
2951                    }
2952                } catch (PackageManager.NameNotFoundException e) {
2953                    Slog.w(TAG, "Unable to retrieve gids", e);
2954                }
2955
2956                /*
2957                 * Add shared application and profile GIDs so applications can share some
2958                 * resources like shared libraries and access user-wide resources
2959                 */
2960                if (permGids == null) {
2961                    gids = new int[2];
2962                } else {
2963                    gids = new int[permGids.length + 2];
2964                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2965                }
2966                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2967                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2968            }
2969            checkTime(startTime, "startProcess: building args");
2970            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2971                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2972                        && mTopComponent != null
2973                        && app.processName.equals(mTopComponent.getPackageName())) {
2974                    uid = 0;
2975                }
2976                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2977                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2978                    uid = 0;
2979                }
2980            }
2981            int debugFlags = 0;
2982            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2983                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2984                // Also turn on CheckJNI for debuggable apps. It's quite
2985                // awkward to turn on otherwise.
2986                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2987            }
2988            // Run the app in safe mode if its manifest requests so or the
2989            // system is booted in safe mode.
2990            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2991                mSafeMode == true) {
2992                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2993            }
2994            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2995                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2996            }
2997            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2998                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2999            }
3000            if ("1".equals(SystemProperties.get("debug.assert"))) {
3001                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3002            }
3003
3004            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3005            if (requiredAbi == null) {
3006                requiredAbi = Build.SUPPORTED_ABIS[0];
3007            }
3008
3009            String instructionSet = null;
3010            if (app.info.primaryCpuAbi != null) {
3011                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3012            }
3013
3014            app.gids = gids;
3015            app.requiredAbi = requiredAbi;
3016            app.instructionSet = instructionSet;
3017
3018            // Start the process.  It will either succeed and return a result containing
3019            // the PID of the new process, or else throw a RuntimeException.
3020            boolean isActivityProcess = (entryPoint == null);
3021            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3022            checkTime(startTime, "startProcess: asking zygote to start proc");
3023            Process.ProcessStartResult startResult = Process.start(entryPoint,
3024                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3025                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3026                    app.info.dataDir, entryPointArgs);
3027            checkTime(startTime, "startProcess: returned from zygote!");
3028
3029            if (app.isolated) {
3030                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3031            }
3032            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3033            checkTime(startTime, "startProcess: done updating battery stats");
3034
3035            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3036                    UserHandle.getUserId(uid), startResult.pid, uid,
3037                    app.processName, hostingType,
3038                    hostingNameStr != null ? hostingNameStr : "");
3039
3040            if (app.persistent) {
3041                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3042            }
3043
3044            checkTime(startTime, "startProcess: building log message");
3045            StringBuilder buf = mStringBuilder;
3046            buf.setLength(0);
3047            buf.append("Start proc ");
3048            buf.append(startResult.pid);
3049            buf.append(':');
3050            buf.append(app.processName);
3051            buf.append('/');
3052            UserHandle.formatUid(buf, uid);
3053            if (!isActivityProcess) {
3054                buf.append(" [");
3055                buf.append(entryPoint);
3056                buf.append("]");
3057            }
3058            buf.append(" for ");
3059            buf.append(hostingType);
3060            if (hostingNameStr != null) {
3061                buf.append(" ");
3062                buf.append(hostingNameStr);
3063            }
3064            Slog.i(TAG, buf.toString());
3065            app.setPid(startResult.pid);
3066            app.usingWrapper = startResult.usingWrapper;
3067            app.removed = false;
3068            app.killed = false;
3069            app.killedByAm = false;
3070            checkTime(startTime, "startProcess: starting to update pids map");
3071            synchronized (mPidsSelfLocked) {
3072                this.mPidsSelfLocked.put(startResult.pid, app);
3073                if (isActivityProcess) {
3074                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3075                    msg.obj = app;
3076                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3077                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3078                }
3079            }
3080            checkTime(startTime, "startProcess: done updating pids map");
3081        } catch (RuntimeException e) {
3082            // XXX do better error recovery.
3083            app.setPid(0);
3084            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3085            if (app.isolated) {
3086                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3087            }
3088            Slog.e(TAG, "Failure starting process " + app.processName, e);
3089        }
3090    }
3091
3092    void updateUsageStats(ActivityRecord component, boolean resumed) {
3093        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3094        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3095        if (resumed) {
3096            if (mUsageStatsService != null) {
3097                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3098                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3099            }
3100            synchronized (stats) {
3101                stats.noteActivityResumedLocked(component.app.uid);
3102            }
3103        } else {
3104            if (mUsageStatsService != null) {
3105                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3106                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3107            }
3108            synchronized (stats) {
3109                stats.noteActivityPausedLocked(component.app.uid);
3110            }
3111        }
3112    }
3113
3114    Intent getHomeIntent() {
3115        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3116        intent.setComponent(mTopComponent);
3117        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3118            intent.addCategory(Intent.CATEGORY_HOME);
3119        }
3120        return intent;
3121    }
3122
3123    boolean startHomeActivityLocked(int userId, String reason) {
3124        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3125                && mTopAction == null) {
3126            // We are running in factory test mode, but unable to find
3127            // the factory test app, so just sit around displaying the
3128            // error message and don't try to start anything.
3129            return false;
3130        }
3131        Intent intent = getHomeIntent();
3132        ActivityInfo aInfo =
3133            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3134        if (aInfo != null) {
3135            intent.setComponent(new ComponentName(
3136                    aInfo.applicationInfo.packageName, aInfo.name));
3137            // Don't do this if the home app is currently being
3138            // instrumented.
3139            aInfo = new ActivityInfo(aInfo);
3140            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3141            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3142                    aInfo.applicationInfo.uid, true);
3143            if (app == null || app.instrumentationClass == null) {
3144                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3145                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3146            }
3147        }
3148
3149        return true;
3150    }
3151
3152    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3153        ActivityInfo ai = null;
3154        ComponentName comp = intent.getComponent();
3155        try {
3156            if (comp != null) {
3157                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3158            } else {
3159                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3160                        intent,
3161                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3162                            flags, userId);
3163
3164                if (info != null) {
3165                    ai = info.activityInfo;
3166                }
3167            }
3168        } catch (RemoteException e) {
3169            // ignore
3170        }
3171
3172        return ai;
3173    }
3174
3175    /**
3176     * Starts the "new version setup screen" if appropriate.
3177     */
3178    void startSetupActivityLocked() {
3179        // Only do this once per boot.
3180        if (mCheckedForSetup) {
3181            return;
3182        }
3183
3184        // We will show this screen if the current one is a different
3185        // version than the last one shown, and we are not running in
3186        // low-level factory test mode.
3187        final ContentResolver resolver = mContext.getContentResolver();
3188        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3189                Settings.Global.getInt(resolver,
3190                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3191            mCheckedForSetup = true;
3192
3193            // See if we should be showing the platform update setup UI.
3194            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3195            List<ResolveInfo> ris = mContext.getPackageManager()
3196                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3197
3198            // We don't allow third party apps to replace this.
3199            ResolveInfo ri = null;
3200            for (int i=0; ris != null && i<ris.size(); i++) {
3201                if ((ris.get(i).activityInfo.applicationInfo.flags
3202                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3203                    ri = ris.get(i);
3204                    break;
3205                }
3206            }
3207
3208            if (ri != null) {
3209                String vers = ri.activityInfo.metaData != null
3210                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3211                        : null;
3212                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3213                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3214                            Intent.METADATA_SETUP_VERSION);
3215                }
3216                String lastVers = Settings.Secure.getString(
3217                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3218                if (vers != null && !vers.equals(lastVers)) {
3219                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3220                    intent.setComponent(new ComponentName(
3221                            ri.activityInfo.packageName, ri.activityInfo.name));
3222                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3223                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3224                            null);
3225                }
3226            }
3227        }
3228    }
3229
3230    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3231        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3232    }
3233
3234    void enforceNotIsolatedCaller(String caller) {
3235        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3236            throw new SecurityException("Isolated process not allowed to call " + caller);
3237        }
3238    }
3239
3240    void enforceShellRestriction(String restriction, int userHandle) {
3241        if (Binder.getCallingUid() == Process.SHELL_UID) {
3242            if (userHandle < 0
3243                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3244                throw new SecurityException("Shell does not have permission to access user "
3245                        + userHandle);
3246            }
3247        }
3248    }
3249
3250    @Override
3251    public int getFrontActivityScreenCompatMode() {
3252        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3253        synchronized (this) {
3254            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3255        }
3256    }
3257
3258    @Override
3259    public void setFrontActivityScreenCompatMode(int mode) {
3260        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3261                "setFrontActivityScreenCompatMode");
3262        synchronized (this) {
3263            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3264        }
3265    }
3266
3267    @Override
3268    public int getPackageScreenCompatMode(String packageName) {
3269        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3270        synchronized (this) {
3271            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3272        }
3273    }
3274
3275    @Override
3276    public void setPackageScreenCompatMode(String packageName, int mode) {
3277        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3278                "setPackageScreenCompatMode");
3279        synchronized (this) {
3280            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3281        }
3282    }
3283
3284    @Override
3285    public boolean getPackageAskScreenCompat(String packageName) {
3286        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3287        synchronized (this) {
3288            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3289        }
3290    }
3291
3292    @Override
3293    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3294        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3295                "setPackageAskScreenCompat");
3296        synchronized (this) {
3297            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3298        }
3299    }
3300
3301    private void dispatchProcessesChanged() {
3302        int N;
3303        synchronized (this) {
3304            N = mPendingProcessChanges.size();
3305            if (mActiveProcessChanges.length < N) {
3306                mActiveProcessChanges = new ProcessChangeItem[N];
3307            }
3308            mPendingProcessChanges.toArray(mActiveProcessChanges);
3309            mAvailProcessChanges.addAll(mPendingProcessChanges);
3310            mPendingProcessChanges.clear();
3311            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3312        }
3313
3314        int i = mProcessObservers.beginBroadcast();
3315        while (i > 0) {
3316            i--;
3317            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3318            if (observer != null) {
3319                try {
3320                    for (int j=0; j<N; j++) {
3321                        ProcessChangeItem item = mActiveProcessChanges[j];
3322                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3323                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3324                                    + item.pid + " uid=" + item.uid + ": "
3325                                    + item.foregroundActivities);
3326                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3327                                    item.foregroundActivities);
3328                        }
3329                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3330                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3331                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3332                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3333                        }
3334                    }
3335                } catch (RemoteException e) {
3336                }
3337            }
3338        }
3339        mProcessObservers.finishBroadcast();
3340    }
3341
3342    private void dispatchProcessDied(int pid, int uid) {
3343        int i = mProcessObservers.beginBroadcast();
3344        while (i > 0) {
3345            i--;
3346            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3347            if (observer != null) {
3348                try {
3349                    observer.onProcessDied(pid, uid);
3350                } catch (RemoteException e) {
3351                }
3352            }
3353        }
3354        mProcessObservers.finishBroadcast();
3355    }
3356
3357    @Override
3358    public final int startActivity(IApplicationThread caller, String callingPackage,
3359            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3360            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3361        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3362            resultWho, requestCode, startFlags, profilerInfo, options,
3363            UserHandle.getCallingUserId());
3364    }
3365
3366    @Override
3367    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3368            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3369            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3370        enforceNotIsolatedCaller("startActivity");
3371        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3372                false, ALLOW_FULL_ONLY, "startActivity", null);
3373        // TODO: Switch to user app stacks here.
3374        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3375                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3376                profilerInfo, null, null, options, userId, null, null);
3377    }
3378
3379    @Override
3380    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3381            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3382            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3383
3384        // This is very dangerous -- it allows you to perform a start activity (including
3385        // permission grants) as any app that may launch one of your own activities.  So
3386        // we will only allow this to be done from activities that are part of the core framework,
3387        // and then only when they are running as the system.
3388        final ActivityRecord sourceRecord;
3389        final int targetUid;
3390        final String targetPackage;
3391        synchronized (this) {
3392            if (resultTo == null) {
3393                throw new SecurityException("Must be called from an activity");
3394            }
3395            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3396            if (sourceRecord == null) {
3397                throw new SecurityException("Called with bad activity token: " + resultTo);
3398            }
3399            if (!sourceRecord.info.packageName.equals("android")) {
3400                throw new SecurityException(
3401                        "Must be called from an activity that is declared in the android package");
3402            }
3403            if (sourceRecord.app == null) {
3404                throw new SecurityException("Called without a process attached to activity");
3405            }
3406            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3407                // This is still okay, as long as this activity is running under the
3408                // uid of the original calling activity.
3409                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3410                    throw new SecurityException(
3411                            "Calling activity in uid " + sourceRecord.app.uid
3412                                    + " must be system uid or original calling uid "
3413                                    + sourceRecord.launchedFromUid);
3414                }
3415            }
3416            targetUid = sourceRecord.launchedFromUid;
3417            targetPackage = sourceRecord.launchedFromPackage;
3418        }
3419
3420        if (userId == UserHandle.USER_NULL) {
3421            userId = UserHandle.getUserId(sourceRecord.app.uid);
3422        }
3423
3424        // TODO: Switch to user app stacks here.
3425        try {
3426            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3427                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3428                    null, null, options, userId, null, null);
3429            return ret;
3430        } catch (SecurityException e) {
3431            // XXX need to figure out how to propagate to original app.
3432            // A SecurityException here is generally actually a fault of the original
3433            // calling activity (such as a fairly granting permissions), so propagate it
3434            // back to them.
3435            /*
3436            StringBuilder msg = new StringBuilder();
3437            msg.append("While launching");
3438            msg.append(intent.toString());
3439            msg.append(": ");
3440            msg.append(e.getMessage());
3441            */
3442            throw e;
3443        }
3444    }
3445
3446    @Override
3447    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3448            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3449            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3450        enforceNotIsolatedCaller("startActivityAndWait");
3451        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3452                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3453        WaitResult res = new WaitResult();
3454        // TODO: Switch to user app stacks here.
3455        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3456                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3457                options, userId, null, null);
3458        return res;
3459    }
3460
3461    @Override
3462    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3463            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3464            int startFlags, Configuration config, Bundle options, int userId) {
3465        enforceNotIsolatedCaller("startActivityWithConfig");
3466        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3467                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3468        // TODO: Switch to user app stacks here.
3469        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3470                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3471                null, null, config, options, userId, null, null);
3472        return ret;
3473    }
3474
3475    @Override
3476    public int startActivityIntentSender(IApplicationThread caller,
3477            IntentSender intent, Intent fillInIntent, String resolvedType,
3478            IBinder resultTo, String resultWho, int requestCode,
3479            int flagsMask, int flagsValues, Bundle options) {
3480        enforceNotIsolatedCaller("startActivityIntentSender");
3481        // Refuse possible leaked file descriptors
3482        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3483            throw new IllegalArgumentException("File descriptors passed in Intent");
3484        }
3485
3486        IIntentSender sender = intent.getTarget();
3487        if (!(sender instanceof PendingIntentRecord)) {
3488            throw new IllegalArgumentException("Bad PendingIntent object");
3489        }
3490
3491        PendingIntentRecord pir = (PendingIntentRecord)sender;
3492
3493        synchronized (this) {
3494            // If this is coming from the currently resumed activity, it is
3495            // effectively saying that app switches are allowed at this point.
3496            final ActivityStack stack = getFocusedStack();
3497            if (stack.mResumedActivity != null &&
3498                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3499                mAppSwitchesAllowedTime = 0;
3500            }
3501        }
3502        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3503                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3504        return ret;
3505    }
3506
3507    @Override
3508    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3509            Intent intent, String resolvedType, IVoiceInteractionSession session,
3510            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3511            Bundle options, int userId) {
3512        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3513                != PackageManager.PERMISSION_GRANTED) {
3514            String msg = "Permission Denial: startVoiceActivity() from pid="
3515                    + Binder.getCallingPid()
3516                    + ", uid=" + Binder.getCallingUid()
3517                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3518            Slog.w(TAG, msg);
3519            throw new SecurityException(msg);
3520        }
3521        if (session == null || interactor == null) {
3522            throw new NullPointerException("null session or interactor");
3523        }
3524        userId = handleIncomingUser(callingPid, callingUid, userId,
3525                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3526        // TODO: Switch to user app stacks here.
3527        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3528                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3529                null, options, userId, null, null);
3530    }
3531
3532    @Override
3533    public boolean startNextMatchingActivity(IBinder callingActivity,
3534            Intent intent, Bundle options) {
3535        // Refuse possible leaked file descriptors
3536        if (intent != null && intent.hasFileDescriptors() == true) {
3537            throw new IllegalArgumentException("File descriptors passed in Intent");
3538        }
3539
3540        synchronized (this) {
3541            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3542            if (r == null) {
3543                ActivityOptions.abort(options);
3544                return false;
3545            }
3546            if (r.app == null || r.app.thread == null) {
3547                // The caller is not running...  d'oh!
3548                ActivityOptions.abort(options);
3549                return false;
3550            }
3551            intent = new Intent(intent);
3552            // The caller is not allowed to change the data.
3553            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3554            // And we are resetting to find the next component...
3555            intent.setComponent(null);
3556
3557            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3558
3559            ActivityInfo aInfo = null;
3560            try {
3561                List<ResolveInfo> resolves =
3562                    AppGlobals.getPackageManager().queryIntentActivities(
3563                            intent, r.resolvedType,
3564                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3565                            UserHandle.getCallingUserId());
3566
3567                // Look for the original activity in the list...
3568                final int N = resolves != null ? resolves.size() : 0;
3569                for (int i=0; i<N; i++) {
3570                    ResolveInfo rInfo = resolves.get(i);
3571                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3572                            && rInfo.activityInfo.name.equals(r.info.name)) {
3573                        // We found the current one...  the next matching is
3574                        // after it.
3575                        i++;
3576                        if (i<N) {
3577                            aInfo = resolves.get(i).activityInfo;
3578                        }
3579                        if (debug) {
3580                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3581                                    + "/" + r.info.name);
3582                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3583                                    + "/" + aInfo.name);
3584                        }
3585                        break;
3586                    }
3587                }
3588            } catch (RemoteException e) {
3589            }
3590
3591            if (aInfo == null) {
3592                // Nobody who is next!
3593                ActivityOptions.abort(options);
3594                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3595                return false;
3596            }
3597
3598            intent.setComponent(new ComponentName(
3599                    aInfo.applicationInfo.packageName, aInfo.name));
3600            intent.setFlags(intent.getFlags()&~(
3601                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3602                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3603                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3604                    Intent.FLAG_ACTIVITY_NEW_TASK));
3605
3606            // Okay now we need to start the new activity, replacing the
3607            // currently running activity.  This is a little tricky because
3608            // we want to start the new one as if the current one is finished,
3609            // but not finish the current one first so that there is no flicker.
3610            // And thus...
3611            final boolean wasFinishing = r.finishing;
3612            r.finishing = true;
3613
3614            // Propagate reply information over to the new activity.
3615            final ActivityRecord resultTo = r.resultTo;
3616            final String resultWho = r.resultWho;
3617            final int requestCode = r.requestCode;
3618            r.resultTo = null;
3619            if (resultTo != null) {
3620                resultTo.removeResultsLocked(r, resultWho, requestCode);
3621            }
3622
3623            final long origId = Binder.clearCallingIdentity();
3624            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3625                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3626                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3627                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3628            Binder.restoreCallingIdentity(origId);
3629
3630            r.finishing = wasFinishing;
3631            if (res != ActivityManager.START_SUCCESS) {
3632                return false;
3633            }
3634            return true;
3635        }
3636    }
3637
3638    @Override
3639    public final int startActivityFromRecents(int taskId, Bundle options) {
3640        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3641            String msg = "Permission Denial: startActivityFromRecents called without " +
3642                    START_TASKS_FROM_RECENTS;
3643            Slog.w(TAG, msg);
3644            throw new SecurityException(msg);
3645        }
3646        return startActivityFromRecentsInner(taskId, options);
3647    }
3648
3649    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3650        final TaskRecord task;
3651        final int callingUid;
3652        final String callingPackage;
3653        final Intent intent;
3654        final int userId;
3655        synchronized (this) {
3656            task = mRecentTasks.taskForIdLocked(taskId);
3657            if (task == null) {
3658                throw new IllegalArgumentException("Task " + taskId + " not found.");
3659            }
3660            if (task.getRootActivity() != null) {
3661                moveTaskToFrontLocked(task.taskId, 0, null);
3662                return ActivityManager.START_TASK_TO_FRONT;
3663            }
3664            callingUid = task.mCallingUid;
3665            callingPackage = task.mCallingPackage;
3666            intent = task.intent;
3667            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3668            userId = task.userId;
3669        }
3670        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3671                options, userId, null, task);
3672    }
3673
3674    final int startActivityInPackage(int uid, String callingPackage,
3675            Intent intent, String resolvedType, IBinder resultTo,
3676            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3677            IActivityContainer container, TaskRecord inTask) {
3678
3679        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3680                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3681
3682        // TODO: Switch to user app stacks here.
3683        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3684                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3685                null, null, null, options, userId, container, inTask);
3686        return ret;
3687    }
3688
3689    @Override
3690    public final int startActivities(IApplicationThread caller, String callingPackage,
3691            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3692            int userId) {
3693        enforceNotIsolatedCaller("startActivities");
3694        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3695                false, ALLOW_FULL_ONLY, "startActivity", null);
3696        // TODO: Switch to user app stacks here.
3697        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3698                resolvedTypes, resultTo, options, userId);
3699        return ret;
3700    }
3701
3702    final int startActivitiesInPackage(int uid, String callingPackage,
3703            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3704            Bundle options, int userId) {
3705
3706        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3707                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3708        // TODO: Switch to user app stacks here.
3709        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3710                resultTo, options, userId);
3711        return ret;
3712    }
3713
3714    @Override
3715    public void reportActivityFullyDrawn(IBinder token) {
3716        synchronized (this) {
3717            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3718            if (r == null) {
3719                return;
3720            }
3721            r.reportFullyDrawnLocked();
3722        }
3723    }
3724
3725    @Override
3726    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3727        synchronized (this) {
3728            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3729            if (r == null) {
3730                return;
3731            }
3732            final long origId = Binder.clearCallingIdentity();
3733            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3734            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3735                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3736            if (config != null) {
3737                r.frozenBeforeDestroy = true;
3738                if (!updateConfigurationLocked(config, r, false, false)) {
3739                    mStackSupervisor.resumeTopActivitiesLocked();
3740                }
3741            }
3742            Binder.restoreCallingIdentity(origId);
3743        }
3744    }
3745
3746    @Override
3747    public int getRequestedOrientation(IBinder token) {
3748        synchronized (this) {
3749            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3750            if (r == null) {
3751                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3752            }
3753            return mWindowManager.getAppOrientation(r.appToken);
3754        }
3755    }
3756
3757    /**
3758     * This is the internal entry point for handling Activity.finish().
3759     *
3760     * @param token The Binder token referencing the Activity we want to finish.
3761     * @param resultCode Result code, if any, from this Activity.
3762     * @param resultData Result data (Intent), if any, from this Activity.
3763     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3764     *            the root Activity in the task.
3765     *
3766     * @return Returns true if the activity successfully finished, or false if it is still running.
3767     */
3768    @Override
3769    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3770            boolean finishTask) {
3771        // Refuse possible leaked file descriptors
3772        if (resultData != null && resultData.hasFileDescriptors() == true) {
3773            throw new IllegalArgumentException("File descriptors passed in Intent");
3774        }
3775
3776        synchronized(this) {
3777            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3778            if (r == null) {
3779                return true;
3780            }
3781            // Keep track of the root activity of the task before we finish it
3782            TaskRecord tr = r.task;
3783            ActivityRecord rootR = tr.getRootActivity();
3784            if (rootR == null) {
3785                Slog.w(TAG, "Finishing task with all activities already finished");
3786            }
3787            // Do not allow task to finish in Lock Task mode.
3788            if (tr == mStackSupervisor.mLockTaskModeTask) {
3789                if (rootR == r) {
3790                    Slog.i(TAG, "Not finishing task in lock task mode");
3791                    mStackSupervisor.showLockTaskToast();
3792                    return false;
3793                }
3794            }
3795            if (mController != null) {
3796                // Find the first activity that is not finishing.
3797                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3798                if (next != null) {
3799                    // ask watcher if this is allowed
3800                    boolean resumeOK = true;
3801                    try {
3802                        resumeOK = mController.activityResuming(next.packageName);
3803                    } catch (RemoteException e) {
3804                        mController = null;
3805                        Watchdog.getInstance().setActivityController(null);
3806                    }
3807
3808                    if (!resumeOK) {
3809                        Slog.i(TAG, "Not finishing activity because controller resumed");
3810                        return false;
3811                    }
3812                }
3813            }
3814            final long origId = Binder.clearCallingIdentity();
3815            try {
3816                boolean res;
3817                if (finishTask && r == rootR) {
3818                    // If requested, remove the task that is associated to this activity only if it
3819                    // was the root activity in the task. The result code and data is ignored
3820                    // because we don't support returning them across task boundaries.
3821                    res = removeTaskByIdLocked(tr.taskId, false);
3822                    if (!res) {
3823                        Slog.i(TAG, "Removing task failed to finish activity");
3824                    }
3825                } else {
3826                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3827                            resultData, "app-request", true);
3828                    if (!res) {
3829                        Slog.i(TAG, "Failed to finish by app-request");
3830                    }
3831                }
3832                return res;
3833            } finally {
3834                Binder.restoreCallingIdentity(origId);
3835            }
3836        }
3837    }
3838
3839    @Override
3840    public final void finishHeavyWeightApp() {
3841        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3842                != PackageManager.PERMISSION_GRANTED) {
3843            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3844                    + Binder.getCallingPid()
3845                    + ", uid=" + Binder.getCallingUid()
3846                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3847            Slog.w(TAG, msg);
3848            throw new SecurityException(msg);
3849        }
3850
3851        synchronized(this) {
3852            if (mHeavyWeightProcess == null) {
3853                return;
3854            }
3855
3856            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3857                    mHeavyWeightProcess.activities);
3858            for (int i=0; i<activities.size(); i++) {
3859                ActivityRecord r = activities.get(i);
3860                if (!r.finishing) {
3861                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3862                            null, "finish-heavy", true);
3863                }
3864            }
3865
3866            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3867                    mHeavyWeightProcess.userId, 0));
3868            mHeavyWeightProcess = null;
3869        }
3870    }
3871
3872    @Override
3873    public void crashApplication(int uid, int initialPid, String packageName,
3874            String message) {
3875        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3876                != PackageManager.PERMISSION_GRANTED) {
3877            String msg = "Permission Denial: crashApplication() from pid="
3878                    + Binder.getCallingPid()
3879                    + ", uid=" + Binder.getCallingUid()
3880                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3881            Slog.w(TAG, msg);
3882            throw new SecurityException(msg);
3883        }
3884
3885        synchronized(this) {
3886            ProcessRecord proc = null;
3887
3888            // Figure out which process to kill.  We don't trust that initialPid
3889            // still has any relation to current pids, so must scan through the
3890            // list.
3891            synchronized (mPidsSelfLocked) {
3892                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3893                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3894                    if (p.uid != uid) {
3895                        continue;
3896                    }
3897                    if (p.pid == initialPid) {
3898                        proc = p;
3899                        break;
3900                    }
3901                    if (p.pkgList.containsKey(packageName)) {
3902                        proc = p;
3903                    }
3904                }
3905            }
3906
3907            if (proc == null) {
3908                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3909                        + " initialPid=" + initialPid
3910                        + " packageName=" + packageName);
3911                return;
3912            }
3913
3914            if (proc.thread != null) {
3915                if (proc.pid == Process.myPid()) {
3916                    Log.w(TAG, "crashApplication: trying to crash self!");
3917                    return;
3918                }
3919                long ident = Binder.clearCallingIdentity();
3920                try {
3921                    proc.thread.scheduleCrash(message);
3922                } catch (RemoteException e) {
3923                }
3924                Binder.restoreCallingIdentity(ident);
3925            }
3926        }
3927    }
3928
3929    @Override
3930    public final void finishSubActivity(IBinder token, String resultWho,
3931            int requestCode) {
3932        synchronized(this) {
3933            final long origId = Binder.clearCallingIdentity();
3934            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3935            if (r != null) {
3936                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3937            }
3938            Binder.restoreCallingIdentity(origId);
3939        }
3940    }
3941
3942    @Override
3943    public boolean finishActivityAffinity(IBinder token) {
3944        synchronized(this) {
3945            final long origId = Binder.clearCallingIdentity();
3946            try {
3947                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3948
3949                ActivityRecord rootR = r.task.getRootActivity();
3950                // Do not allow task to finish in Lock Task mode.
3951                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3952                    if (rootR == r) {
3953                        mStackSupervisor.showLockTaskToast();
3954                        return false;
3955                    }
3956                }
3957                boolean res = false;
3958                if (r != null) {
3959                    res = r.task.stack.finishActivityAffinityLocked(r);
3960                }
3961                return res;
3962            } finally {
3963                Binder.restoreCallingIdentity(origId);
3964            }
3965        }
3966    }
3967
3968    @Override
3969    public void finishVoiceTask(IVoiceInteractionSession session) {
3970        synchronized(this) {
3971            final long origId = Binder.clearCallingIdentity();
3972            try {
3973                mStackSupervisor.finishVoiceTask(session);
3974            } finally {
3975                Binder.restoreCallingIdentity(origId);
3976            }
3977        }
3978
3979    }
3980
3981    @Override
3982    public boolean releaseActivityInstance(IBinder token) {
3983        synchronized(this) {
3984            final long origId = Binder.clearCallingIdentity();
3985            try {
3986                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3987                if (r.task == null || r.task.stack == null) {
3988                    return false;
3989                }
3990                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
3991            } finally {
3992                Binder.restoreCallingIdentity(origId);
3993            }
3994        }
3995    }
3996
3997    @Override
3998    public void releaseSomeActivities(IApplicationThread appInt) {
3999        synchronized(this) {
4000            final long origId = Binder.clearCallingIdentity();
4001            try {
4002                ProcessRecord app = getRecordForAppLocked(appInt);
4003                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4004            } finally {
4005                Binder.restoreCallingIdentity(origId);
4006            }
4007        }
4008    }
4009
4010    @Override
4011    public boolean willActivityBeVisible(IBinder token) {
4012        synchronized(this) {
4013            ActivityStack stack = ActivityRecord.getStackLocked(token);
4014            if (stack != null) {
4015                return stack.willActivityBeVisibleLocked(token);
4016            }
4017            return false;
4018        }
4019    }
4020
4021    @Override
4022    public void overridePendingTransition(IBinder token, String packageName,
4023            int enterAnim, int exitAnim) {
4024        synchronized(this) {
4025            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4026            if (self == null) {
4027                return;
4028            }
4029
4030            final long origId = Binder.clearCallingIdentity();
4031
4032            if (self.state == ActivityState.RESUMED
4033                    || self.state == ActivityState.PAUSING) {
4034                mWindowManager.overridePendingAppTransition(packageName,
4035                        enterAnim, exitAnim, null);
4036            }
4037
4038            Binder.restoreCallingIdentity(origId);
4039        }
4040    }
4041
4042    /**
4043     * Main function for removing an existing process from the activity manager
4044     * as a result of that process going away.  Clears out all connections
4045     * to the process.
4046     */
4047    private final void handleAppDiedLocked(ProcessRecord app,
4048            boolean restarting, boolean allowRestart) {
4049        int pid = app.pid;
4050        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4051        if (!kept && !restarting) {
4052            removeLruProcessLocked(app);
4053            if (pid > 0) {
4054                ProcessList.remove(pid);
4055            }
4056        }
4057
4058        if (mProfileProc == app) {
4059            clearProfilerLocked();
4060        }
4061
4062        // Remove this application's activities from active lists.
4063        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4064
4065        app.activities.clear();
4066
4067        if (app.instrumentationClass != null) {
4068            Slog.w(TAG, "Crash of app " + app.processName
4069                  + " running instrumentation " + app.instrumentationClass);
4070            Bundle info = new Bundle();
4071            info.putString("shortMsg", "Process crashed.");
4072            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4073        }
4074
4075        if (!restarting) {
4076            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4077                // If there was nothing to resume, and we are not already
4078                // restarting this process, but there is a visible activity that
4079                // is hosted by the process...  then make sure all visible
4080                // activities are running, taking care of restarting this
4081                // process.
4082                if (hasVisibleActivities) {
4083                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4084                }
4085            }
4086        }
4087    }
4088
4089    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4090        IBinder threadBinder = thread.asBinder();
4091        // Find the application record.
4092        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4093            ProcessRecord rec = mLruProcesses.get(i);
4094            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4095                return i;
4096            }
4097        }
4098        return -1;
4099    }
4100
4101    final ProcessRecord getRecordForAppLocked(
4102            IApplicationThread thread) {
4103        if (thread == null) {
4104            return null;
4105        }
4106
4107        int appIndex = getLRURecordIndexForAppLocked(thread);
4108        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4109    }
4110
4111    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4112        // If there are no longer any background processes running,
4113        // and the app that died was not running instrumentation,
4114        // then tell everyone we are now low on memory.
4115        boolean haveBg = false;
4116        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4117            ProcessRecord rec = mLruProcesses.get(i);
4118            if (rec.thread != null
4119                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4120                haveBg = true;
4121                break;
4122            }
4123        }
4124
4125        if (!haveBg) {
4126            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4127            if (doReport) {
4128                long now = SystemClock.uptimeMillis();
4129                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4130                    doReport = false;
4131                } else {
4132                    mLastMemUsageReportTime = now;
4133                }
4134            }
4135            final ArrayList<ProcessMemInfo> memInfos
4136                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4137            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4138            long now = SystemClock.uptimeMillis();
4139            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4140                ProcessRecord rec = mLruProcesses.get(i);
4141                if (rec == dyingProc || rec.thread == null) {
4142                    continue;
4143                }
4144                if (doReport) {
4145                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4146                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4147                }
4148                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4149                    // The low memory report is overriding any current
4150                    // state for a GC request.  Make sure to do
4151                    // heavy/important/visible/foreground processes first.
4152                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4153                        rec.lastRequestedGc = 0;
4154                    } else {
4155                        rec.lastRequestedGc = rec.lastLowMemory;
4156                    }
4157                    rec.reportLowMemory = true;
4158                    rec.lastLowMemory = now;
4159                    mProcessesToGc.remove(rec);
4160                    addProcessToGcListLocked(rec);
4161                }
4162            }
4163            if (doReport) {
4164                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4165                mHandler.sendMessage(msg);
4166            }
4167            scheduleAppGcsLocked();
4168        }
4169    }
4170
4171    final void appDiedLocked(ProcessRecord app) {
4172       appDiedLocked(app, app.pid, app.thread);
4173    }
4174
4175    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4176        // First check if this ProcessRecord is actually active for the pid.
4177        synchronized (mPidsSelfLocked) {
4178            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4179            if (curProc != app) {
4180                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4181                return;
4182            }
4183        }
4184
4185        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4186        synchronized (stats) {
4187            stats.noteProcessDiedLocked(app.info.uid, pid);
4188        }
4189
4190        if (!app.killed) {
4191            Process.killProcessQuiet(pid);
4192            Process.killProcessGroup(app.info.uid, pid);
4193            app.killed = true;
4194        }
4195
4196        // Clean up already done if the process has been re-started.
4197        if (app.pid == pid && app.thread != null &&
4198                app.thread.asBinder() == thread.asBinder()) {
4199            boolean doLowMem = app.instrumentationClass == null;
4200            boolean doOomAdj = doLowMem;
4201            if (!app.killedByAm) {
4202                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4203                        + ") has died");
4204                mAllowLowerMemLevel = true;
4205            } else {
4206                // Note that we always want to do oom adj to update our state with the
4207                // new number of procs.
4208                mAllowLowerMemLevel = false;
4209                doLowMem = false;
4210            }
4211            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4212            if (DEBUG_CLEANUP) Slog.v(
4213                TAG, "Dying app: " + app + ", pid: " + pid
4214                + ", thread: " + thread.asBinder());
4215            handleAppDiedLocked(app, false, true);
4216
4217            if (doOomAdj) {
4218                updateOomAdjLocked();
4219            }
4220            if (doLowMem) {
4221                doLowMemReportIfNeededLocked(app);
4222            }
4223        } else if (app.pid != pid) {
4224            // A new process has already been started.
4225            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4226                    + ") has died and restarted (pid " + app.pid + ").");
4227            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4228        } else if (DEBUG_PROCESSES) {
4229            Slog.d(TAG, "Received spurious death notification for thread "
4230                    + thread.asBinder());
4231        }
4232    }
4233
4234    /**
4235     * If a stack trace dump file is configured, dump process stack traces.
4236     * @param clearTraces causes the dump file to be erased prior to the new
4237     *    traces being written, if true; when false, the new traces will be
4238     *    appended to any existing file content.
4239     * @param firstPids of dalvik VM processes to dump stack traces for first
4240     * @param lastPids of dalvik VM processes to dump stack traces for last
4241     * @param nativeProcs optional list of native process names to dump stack crawls
4242     * @return file containing stack traces, or null if no dump file is configured
4243     */
4244    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4245            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4246        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4247        if (tracesPath == null || tracesPath.length() == 0) {
4248            return null;
4249        }
4250
4251        File tracesFile = new File(tracesPath);
4252        try {
4253            File tracesDir = tracesFile.getParentFile();
4254            if (!tracesDir.exists()) {
4255                tracesDir.mkdirs();
4256                if (!SELinux.restorecon(tracesDir)) {
4257                    return null;
4258                }
4259            }
4260            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4261
4262            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4263            tracesFile.createNewFile();
4264            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4265        } catch (IOException e) {
4266            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4267            return null;
4268        }
4269
4270        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4271        return tracesFile;
4272    }
4273
4274    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4275            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4276        // Use a FileObserver to detect when traces finish writing.
4277        // The order of traces is considered important to maintain for legibility.
4278        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4279            @Override
4280            public synchronized void onEvent(int event, String path) { notify(); }
4281        };
4282
4283        try {
4284            observer.startWatching();
4285
4286            // First collect all of the stacks of the most important pids.
4287            if (firstPids != null) {
4288                try {
4289                    int num = firstPids.size();
4290                    for (int i = 0; i < num; i++) {
4291                        synchronized (observer) {
4292                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4293                            observer.wait(200);  // Wait for write-close, give up after 200msec
4294                        }
4295                    }
4296                } catch (InterruptedException e) {
4297                    Slog.wtf(TAG, e);
4298                }
4299            }
4300
4301            // Next collect the stacks of the native pids
4302            if (nativeProcs != null) {
4303                int[] pids = Process.getPidsForCommands(nativeProcs);
4304                if (pids != null) {
4305                    for (int pid : pids) {
4306                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4307                    }
4308                }
4309            }
4310
4311            // Lastly, measure CPU usage.
4312            if (processCpuTracker != null) {
4313                processCpuTracker.init();
4314                System.gc();
4315                processCpuTracker.update();
4316                try {
4317                    synchronized (processCpuTracker) {
4318                        processCpuTracker.wait(500); // measure over 1/2 second.
4319                    }
4320                } catch (InterruptedException e) {
4321                }
4322                processCpuTracker.update();
4323
4324                // We'll take the stack crawls of just the top apps using CPU.
4325                final int N = processCpuTracker.countWorkingStats();
4326                int numProcs = 0;
4327                for (int i=0; i<N && numProcs<5; i++) {
4328                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4329                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4330                        numProcs++;
4331                        try {
4332                            synchronized (observer) {
4333                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4334                                observer.wait(200);  // Wait for write-close, give up after 200msec
4335                            }
4336                        } catch (InterruptedException e) {
4337                            Slog.wtf(TAG, e);
4338                        }
4339
4340                    }
4341                }
4342            }
4343        } finally {
4344            observer.stopWatching();
4345        }
4346    }
4347
4348    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4349        if (true || IS_USER_BUILD) {
4350            return;
4351        }
4352        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4353        if (tracesPath == null || tracesPath.length() == 0) {
4354            return;
4355        }
4356
4357        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4358        StrictMode.allowThreadDiskWrites();
4359        try {
4360            final File tracesFile = new File(tracesPath);
4361            final File tracesDir = tracesFile.getParentFile();
4362            final File tracesTmp = new File(tracesDir, "__tmp__");
4363            try {
4364                if (!tracesDir.exists()) {
4365                    tracesDir.mkdirs();
4366                    if (!SELinux.restorecon(tracesDir.getPath())) {
4367                        return;
4368                    }
4369                }
4370                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4371
4372                if (tracesFile.exists()) {
4373                    tracesTmp.delete();
4374                    tracesFile.renameTo(tracesTmp);
4375                }
4376                StringBuilder sb = new StringBuilder();
4377                Time tobj = new Time();
4378                tobj.set(System.currentTimeMillis());
4379                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4380                sb.append(": ");
4381                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4382                sb.append(" since ");
4383                sb.append(msg);
4384                FileOutputStream fos = new FileOutputStream(tracesFile);
4385                fos.write(sb.toString().getBytes());
4386                if (app == null) {
4387                    fos.write("\n*** No application process!".getBytes());
4388                }
4389                fos.close();
4390                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4391            } catch (IOException e) {
4392                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4393                return;
4394            }
4395
4396            if (app != null) {
4397                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4398                firstPids.add(app.pid);
4399                dumpStackTraces(tracesPath, firstPids, null, null, null);
4400            }
4401
4402            File lastTracesFile = null;
4403            File curTracesFile = null;
4404            for (int i=9; i>=0; i--) {
4405                String name = String.format(Locale.US, "slow%02d.txt", i);
4406                curTracesFile = new File(tracesDir, name);
4407                if (curTracesFile.exists()) {
4408                    if (lastTracesFile != null) {
4409                        curTracesFile.renameTo(lastTracesFile);
4410                    } else {
4411                        curTracesFile.delete();
4412                    }
4413                }
4414                lastTracesFile = curTracesFile;
4415            }
4416            tracesFile.renameTo(curTracesFile);
4417            if (tracesTmp.exists()) {
4418                tracesTmp.renameTo(tracesFile);
4419            }
4420        } finally {
4421            StrictMode.setThreadPolicy(oldPolicy);
4422        }
4423    }
4424
4425    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4426            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4427        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4428        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4429
4430        if (mController != null) {
4431            try {
4432                // 0 == continue, -1 = kill process immediately
4433                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4434                if (res < 0 && app.pid != MY_PID) {
4435                    app.kill("anr", true);
4436                }
4437            } catch (RemoteException e) {
4438                mController = null;
4439                Watchdog.getInstance().setActivityController(null);
4440            }
4441        }
4442
4443        long anrTime = SystemClock.uptimeMillis();
4444        if (MONITOR_CPU_USAGE) {
4445            updateCpuStatsNow();
4446        }
4447
4448        synchronized (this) {
4449            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4450            if (mShuttingDown) {
4451                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4452                return;
4453            } else if (app.notResponding) {
4454                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4455                return;
4456            } else if (app.crashing) {
4457                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4458                return;
4459            }
4460
4461            // In case we come through here for the same app before completing
4462            // this one, mark as anring now so we will bail out.
4463            app.notResponding = true;
4464
4465            // Log the ANR to the event log.
4466            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4467                    app.processName, app.info.flags, annotation);
4468
4469            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4470            firstPids.add(app.pid);
4471
4472            int parentPid = app.pid;
4473            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4474            if (parentPid != app.pid) firstPids.add(parentPid);
4475
4476            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4477
4478            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4479                ProcessRecord r = mLruProcesses.get(i);
4480                if (r != null && r.thread != null) {
4481                    int pid = r.pid;
4482                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4483                        if (r.persistent) {
4484                            firstPids.add(pid);
4485                        } else {
4486                            lastPids.put(pid, Boolean.TRUE);
4487                        }
4488                    }
4489                }
4490            }
4491        }
4492
4493        // Log the ANR to the main log.
4494        StringBuilder info = new StringBuilder();
4495        info.setLength(0);
4496        info.append("ANR in ").append(app.processName);
4497        if (activity != null && activity.shortComponentName != null) {
4498            info.append(" (").append(activity.shortComponentName).append(")");
4499        }
4500        info.append("\n");
4501        info.append("PID: ").append(app.pid).append("\n");
4502        if (annotation != null) {
4503            info.append("Reason: ").append(annotation).append("\n");
4504        }
4505        if (parent != null && parent != activity) {
4506            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4507        }
4508
4509        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4510
4511        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4512                NATIVE_STACKS_OF_INTEREST);
4513
4514        String cpuInfo = null;
4515        if (MONITOR_CPU_USAGE) {
4516            updateCpuStatsNow();
4517            synchronized (mProcessCpuTracker) {
4518                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4519            }
4520            info.append(processCpuTracker.printCurrentLoad());
4521            info.append(cpuInfo);
4522        }
4523
4524        info.append(processCpuTracker.printCurrentState(anrTime));
4525
4526        Slog.e(TAG, info.toString());
4527        if (tracesFile == null) {
4528            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4529            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4530        }
4531
4532        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4533                cpuInfo, tracesFile, null);
4534
4535        if (mController != null) {
4536            try {
4537                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4538                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4539                if (res != 0) {
4540                    if (res < 0 && app.pid != MY_PID) {
4541                        app.kill("anr", true);
4542                    } else {
4543                        synchronized (this) {
4544                            mServices.scheduleServiceTimeoutLocked(app);
4545                        }
4546                    }
4547                    return;
4548                }
4549            } catch (RemoteException e) {
4550                mController = null;
4551                Watchdog.getInstance().setActivityController(null);
4552            }
4553        }
4554
4555        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4556        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4557                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4558
4559        synchronized (this) {
4560            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
4561
4562            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4563                app.kill("bg anr", true);
4564                return;
4565            }
4566
4567            // Set the app's notResponding state, and look up the errorReportReceiver
4568            makeAppNotRespondingLocked(app,
4569                    activity != null ? activity.shortComponentName : null,
4570                    annotation != null ? "ANR " + annotation : "ANR",
4571                    info.toString());
4572
4573            // Bring up the infamous App Not Responding dialog
4574            Message msg = Message.obtain();
4575            HashMap<String, Object> map = new HashMap<String, Object>();
4576            msg.what = SHOW_NOT_RESPONDING_MSG;
4577            msg.obj = map;
4578            msg.arg1 = aboveSystem ? 1 : 0;
4579            map.put("app", app);
4580            if (activity != null) {
4581                map.put("activity", activity);
4582            }
4583
4584            mHandler.sendMessage(msg);
4585        }
4586    }
4587
4588    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4589        if (!mLaunchWarningShown) {
4590            mLaunchWarningShown = true;
4591            mHandler.post(new Runnable() {
4592                @Override
4593                public void run() {
4594                    synchronized (ActivityManagerService.this) {
4595                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4596                        d.show();
4597                        mHandler.postDelayed(new Runnable() {
4598                            @Override
4599                            public void run() {
4600                                synchronized (ActivityManagerService.this) {
4601                                    d.dismiss();
4602                                    mLaunchWarningShown = false;
4603                                }
4604                            }
4605                        }, 4000);
4606                    }
4607                }
4608            });
4609        }
4610    }
4611
4612    @Override
4613    public boolean clearApplicationUserData(final String packageName,
4614            final IPackageDataObserver observer, int userId) {
4615        enforceNotIsolatedCaller("clearApplicationUserData");
4616        int uid = Binder.getCallingUid();
4617        int pid = Binder.getCallingPid();
4618        userId = handleIncomingUser(pid, uid,
4619                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4620        long callingId = Binder.clearCallingIdentity();
4621        try {
4622            IPackageManager pm = AppGlobals.getPackageManager();
4623            int pkgUid = -1;
4624            synchronized(this) {
4625                try {
4626                    pkgUid = pm.getPackageUid(packageName, userId);
4627                } catch (RemoteException e) {
4628                }
4629                if (pkgUid == -1) {
4630                    Slog.w(TAG, "Invalid packageName: " + packageName);
4631                    if (observer != null) {
4632                        try {
4633                            observer.onRemoveCompleted(packageName, false);
4634                        } catch (RemoteException e) {
4635                            Slog.i(TAG, "Observer no longer exists.");
4636                        }
4637                    }
4638                    return false;
4639                }
4640                if (uid == pkgUid || checkComponentPermission(
4641                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4642                        pid, uid, -1, true)
4643                        == PackageManager.PERMISSION_GRANTED) {
4644                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4645                } else {
4646                    throw new SecurityException("PID " + pid + " does not have permission "
4647                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4648                                    + " of package " + packageName);
4649                }
4650
4651                // Remove all tasks match the cleared application package and user
4652                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4653                    final TaskRecord tr = mRecentTasks.get(i);
4654                    final String taskPackageName =
4655                            tr.getBaseIntent().getComponent().getPackageName();
4656                    if (tr.userId != userId) continue;
4657                    if (!taskPackageName.equals(packageName)) continue;
4658                    removeTaskByIdLocked(tr.taskId, false);
4659                }
4660            }
4661
4662            try {
4663                // Clear application user data
4664                pm.clearApplicationUserData(packageName, observer, userId);
4665
4666                synchronized(this) {
4667                    // Remove all permissions granted from/to this package
4668                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4669                }
4670
4671                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4672                        Uri.fromParts("package", packageName, null));
4673                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4674                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4675                        null, null, 0, null, null, null, false, false, userId);
4676            } catch (RemoteException e) {
4677            }
4678        } finally {
4679            Binder.restoreCallingIdentity(callingId);
4680        }
4681        return true;
4682    }
4683
4684    @Override
4685    public void killBackgroundProcesses(final String packageName, int userId) {
4686        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4687                != PackageManager.PERMISSION_GRANTED &&
4688                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4689                        != PackageManager.PERMISSION_GRANTED) {
4690            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4691                    + Binder.getCallingPid()
4692                    + ", uid=" + Binder.getCallingUid()
4693                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4694            Slog.w(TAG, msg);
4695            throw new SecurityException(msg);
4696        }
4697
4698        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4699                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4700        long callingId = Binder.clearCallingIdentity();
4701        try {
4702            IPackageManager pm = AppGlobals.getPackageManager();
4703            synchronized(this) {
4704                int appId = -1;
4705                try {
4706                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4707                } catch (RemoteException e) {
4708                }
4709                if (appId == -1) {
4710                    Slog.w(TAG, "Invalid packageName: " + packageName);
4711                    return;
4712                }
4713                killPackageProcessesLocked(packageName, appId, userId,
4714                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4715            }
4716        } finally {
4717            Binder.restoreCallingIdentity(callingId);
4718        }
4719    }
4720
4721    @Override
4722    public void killAllBackgroundProcesses() {
4723        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4724                != PackageManager.PERMISSION_GRANTED) {
4725            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4726                    + Binder.getCallingPid()
4727                    + ", uid=" + Binder.getCallingUid()
4728                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4729            Slog.w(TAG, msg);
4730            throw new SecurityException(msg);
4731        }
4732
4733        long callingId = Binder.clearCallingIdentity();
4734        try {
4735            synchronized(this) {
4736                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4737                final int NP = mProcessNames.getMap().size();
4738                for (int ip=0; ip<NP; ip++) {
4739                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4740                    final int NA = apps.size();
4741                    for (int ia=0; ia<NA; ia++) {
4742                        ProcessRecord app = apps.valueAt(ia);
4743                        if (app.persistent) {
4744                            // we don't kill persistent processes
4745                            continue;
4746                        }
4747                        if (app.removed) {
4748                            procs.add(app);
4749                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4750                            app.removed = true;
4751                            procs.add(app);
4752                        }
4753                    }
4754                }
4755
4756                int N = procs.size();
4757                for (int i=0; i<N; i++) {
4758                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4759                }
4760                mAllowLowerMemLevel = true;
4761                updateOomAdjLocked();
4762                doLowMemReportIfNeededLocked(null);
4763            }
4764        } finally {
4765            Binder.restoreCallingIdentity(callingId);
4766        }
4767    }
4768
4769    @Override
4770    public void forceStopPackage(final String packageName, int userId) {
4771        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4772                != PackageManager.PERMISSION_GRANTED) {
4773            String msg = "Permission Denial: forceStopPackage() from pid="
4774                    + Binder.getCallingPid()
4775                    + ", uid=" + Binder.getCallingUid()
4776                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4777            Slog.w(TAG, msg);
4778            throw new SecurityException(msg);
4779        }
4780        final int callingPid = Binder.getCallingPid();
4781        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4782                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4783        long callingId = Binder.clearCallingIdentity();
4784        try {
4785            IPackageManager pm = AppGlobals.getPackageManager();
4786            synchronized(this) {
4787                int[] users = userId == UserHandle.USER_ALL
4788                        ? getUsersLocked() : new int[] { userId };
4789                for (int user : users) {
4790                    int pkgUid = -1;
4791                    try {
4792                        pkgUid = pm.getPackageUid(packageName, user);
4793                    } catch (RemoteException e) {
4794                    }
4795                    if (pkgUid == -1) {
4796                        Slog.w(TAG, "Invalid packageName: " + packageName);
4797                        continue;
4798                    }
4799                    try {
4800                        pm.setPackageStoppedState(packageName, true, user);
4801                    } catch (RemoteException e) {
4802                    } catch (IllegalArgumentException e) {
4803                        Slog.w(TAG, "Failed trying to unstop package "
4804                                + packageName + ": " + e);
4805                    }
4806                    if (isUserRunningLocked(user, false)) {
4807                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4808                    }
4809                }
4810            }
4811        } finally {
4812            Binder.restoreCallingIdentity(callingId);
4813        }
4814    }
4815
4816    @Override
4817    public void addPackageDependency(String packageName) {
4818        synchronized (this) {
4819            int callingPid = Binder.getCallingPid();
4820            if (callingPid == Process.myPid()) {
4821                //  Yeah, um, no.
4822                return;
4823            }
4824            ProcessRecord proc;
4825            synchronized (mPidsSelfLocked) {
4826                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4827            }
4828            if (proc != null) {
4829                if (proc.pkgDeps == null) {
4830                    proc.pkgDeps = new ArraySet<String>(1);
4831                }
4832                proc.pkgDeps.add(packageName);
4833            }
4834        }
4835    }
4836
4837    /*
4838     * The pkg name and app id have to be specified.
4839     */
4840    @Override
4841    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4842        if (pkg == null) {
4843            return;
4844        }
4845        // Make sure the uid is valid.
4846        if (appid < 0) {
4847            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4848            return;
4849        }
4850        int callerUid = Binder.getCallingUid();
4851        // Only the system server can kill an application
4852        if (callerUid == Process.SYSTEM_UID) {
4853            // Post an aysnc message to kill the application
4854            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4855            msg.arg1 = appid;
4856            msg.arg2 = 0;
4857            Bundle bundle = new Bundle();
4858            bundle.putString("pkg", pkg);
4859            bundle.putString("reason", reason);
4860            msg.obj = bundle;
4861            mHandler.sendMessage(msg);
4862        } else {
4863            throw new SecurityException(callerUid + " cannot kill pkg: " +
4864                    pkg);
4865        }
4866    }
4867
4868    @Override
4869    public void closeSystemDialogs(String reason) {
4870        enforceNotIsolatedCaller("closeSystemDialogs");
4871
4872        final int pid = Binder.getCallingPid();
4873        final int uid = Binder.getCallingUid();
4874        final long origId = Binder.clearCallingIdentity();
4875        try {
4876            synchronized (this) {
4877                // Only allow this from foreground processes, so that background
4878                // applications can't abuse it to prevent system UI from being shown.
4879                if (uid >= Process.FIRST_APPLICATION_UID) {
4880                    ProcessRecord proc;
4881                    synchronized (mPidsSelfLocked) {
4882                        proc = mPidsSelfLocked.get(pid);
4883                    }
4884                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4885                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4886                                + " from background process " + proc);
4887                        return;
4888                    }
4889                }
4890                closeSystemDialogsLocked(reason);
4891            }
4892        } finally {
4893            Binder.restoreCallingIdentity(origId);
4894        }
4895    }
4896
4897    void closeSystemDialogsLocked(String reason) {
4898        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4899        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4900                | Intent.FLAG_RECEIVER_FOREGROUND);
4901        if (reason != null) {
4902            intent.putExtra("reason", reason);
4903        }
4904        mWindowManager.closeSystemDialogs(reason);
4905
4906        mStackSupervisor.closeSystemDialogsLocked();
4907
4908        broadcastIntentLocked(null, null, intent, null,
4909                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4910                Process.SYSTEM_UID, UserHandle.USER_ALL);
4911    }
4912
4913    @Override
4914    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4915        enforceNotIsolatedCaller("getProcessMemoryInfo");
4916        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4917        for (int i=pids.length-1; i>=0; i--) {
4918            ProcessRecord proc;
4919            int oomAdj;
4920            synchronized (this) {
4921                synchronized (mPidsSelfLocked) {
4922                    proc = mPidsSelfLocked.get(pids[i]);
4923                    oomAdj = proc != null ? proc.setAdj : 0;
4924                }
4925            }
4926            infos[i] = new Debug.MemoryInfo();
4927            Debug.getMemoryInfo(pids[i], infos[i]);
4928            if (proc != null) {
4929                synchronized (this) {
4930                    if (proc.thread != null && proc.setAdj == oomAdj) {
4931                        // Record this for posterity if the process has been stable.
4932                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4933                                infos[i].getTotalUss(), false, proc.pkgList);
4934                    }
4935                }
4936            }
4937        }
4938        return infos;
4939    }
4940
4941    @Override
4942    public long[] getProcessPss(int[] pids) {
4943        enforceNotIsolatedCaller("getProcessPss");
4944        long[] pss = new long[pids.length];
4945        for (int i=pids.length-1; i>=0; i--) {
4946            ProcessRecord proc;
4947            int oomAdj;
4948            synchronized (this) {
4949                synchronized (mPidsSelfLocked) {
4950                    proc = mPidsSelfLocked.get(pids[i]);
4951                    oomAdj = proc != null ? proc.setAdj : 0;
4952                }
4953            }
4954            long[] tmpUss = new long[1];
4955            pss[i] = Debug.getPss(pids[i], tmpUss, null);
4956            if (proc != null) {
4957                synchronized (this) {
4958                    if (proc.thread != null && proc.setAdj == oomAdj) {
4959                        // Record this for posterity if the process has been stable.
4960                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4961                    }
4962                }
4963            }
4964        }
4965        return pss;
4966    }
4967
4968    @Override
4969    public void killApplicationProcess(String processName, int uid) {
4970        if (processName == null) {
4971            return;
4972        }
4973
4974        int callerUid = Binder.getCallingUid();
4975        // Only the system server can kill an application
4976        if (callerUid == Process.SYSTEM_UID) {
4977            synchronized (this) {
4978                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4979                if (app != null && app.thread != null) {
4980                    try {
4981                        app.thread.scheduleSuicide();
4982                    } catch (RemoteException e) {
4983                        // If the other end already died, then our work here is done.
4984                    }
4985                } else {
4986                    Slog.w(TAG, "Process/uid not found attempting kill of "
4987                            + processName + " / " + uid);
4988                }
4989            }
4990        } else {
4991            throw new SecurityException(callerUid + " cannot kill app process: " +
4992                    processName);
4993        }
4994    }
4995
4996    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4997        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4998                false, true, false, false, UserHandle.getUserId(uid), reason);
4999        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5000                Uri.fromParts("package", packageName, null));
5001        if (!mProcessesReady) {
5002            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5003                    | Intent.FLAG_RECEIVER_FOREGROUND);
5004        }
5005        intent.putExtra(Intent.EXTRA_UID, uid);
5006        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5007        broadcastIntentLocked(null, null, intent,
5008                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5009                false, false,
5010                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5011    }
5012
5013    private void forceStopUserLocked(int userId, String reason) {
5014        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5015        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5016        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5017                | Intent.FLAG_RECEIVER_FOREGROUND);
5018        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5019        broadcastIntentLocked(null, null, intent,
5020                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5021                false, false,
5022                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5023    }
5024
5025    private final boolean killPackageProcessesLocked(String packageName, int appId,
5026            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5027            boolean doit, boolean evenPersistent, String reason) {
5028        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5029
5030        // Remove all processes this package may have touched: all with the
5031        // same UID (except for the system or root user), and all whose name
5032        // matches the package name.
5033        final int NP = mProcessNames.getMap().size();
5034        for (int ip=0; ip<NP; ip++) {
5035            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5036            final int NA = apps.size();
5037            for (int ia=0; ia<NA; ia++) {
5038                ProcessRecord app = apps.valueAt(ia);
5039                if (app.persistent && !evenPersistent) {
5040                    // we don't kill persistent processes
5041                    continue;
5042                }
5043                if (app.removed) {
5044                    if (doit) {
5045                        procs.add(app);
5046                    }
5047                    continue;
5048                }
5049
5050                // Skip process if it doesn't meet our oom adj requirement.
5051                if (app.setAdj < minOomAdj) {
5052                    continue;
5053                }
5054
5055                // If no package is specified, we call all processes under the
5056                // give user id.
5057                if (packageName == null) {
5058                    if (app.userId != userId) {
5059                        continue;
5060                    }
5061                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5062                        continue;
5063                    }
5064                // Package has been specified, we want to hit all processes
5065                // that match it.  We need to qualify this by the processes
5066                // that are running under the specified app and user ID.
5067                } else {
5068                    final boolean isDep = app.pkgDeps != null
5069                            && app.pkgDeps.contains(packageName);
5070                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5071                        continue;
5072                    }
5073                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5074                        continue;
5075                    }
5076                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5077                        continue;
5078                    }
5079                }
5080
5081                // Process has passed all conditions, kill it!
5082                if (!doit) {
5083                    return true;
5084                }
5085                app.removed = true;
5086                procs.add(app);
5087            }
5088        }
5089
5090        int N = procs.size();
5091        for (int i=0; i<N; i++) {
5092            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5093        }
5094        updateOomAdjLocked();
5095        return N > 0;
5096    }
5097
5098    private final boolean forceStopPackageLocked(String name, int appId,
5099            boolean callerWillRestart, boolean purgeCache, boolean doit,
5100            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5101        int i;
5102        int N;
5103
5104        if (userId == UserHandle.USER_ALL && name == null) {
5105            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5106        }
5107
5108        if (appId < 0 && name != null) {
5109            try {
5110                appId = UserHandle.getAppId(
5111                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5112            } catch (RemoteException e) {
5113            }
5114        }
5115
5116        if (doit) {
5117            if (name != null) {
5118                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5119                        + " user=" + userId + ": " + reason);
5120            } else {
5121                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5122            }
5123
5124            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5125            for (int ip=pmap.size()-1; ip>=0; ip--) {
5126                SparseArray<Long> ba = pmap.valueAt(ip);
5127                for (i=ba.size()-1; i>=0; i--) {
5128                    boolean remove = false;
5129                    final int entUid = ba.keyAt(i);
5130                    if (name != null) {
5131                        if (userId == UserHandle.USER_ALL) {
5132                            if (UserHandle.getAppId(entUid) == appId) {
5133                                remove = true;
5134                            }
5135                        } else {
5136                            if (entUid == UserHandle.getUid(userId, appId)) {
5137                                remove = true;
5138                            }
5139                        }
5140                    } else if (UserHandle.getUserId(entUid) == userId) {
5141                        remove = true;
5142                    }
5143                    if (remove) {
5144                        ba.removeAt(i);
5145                    }
5146                }
5147                if (ba.size() == 0) {
5148                    pmap.removeAt(ip);
5149                }
5150            }
5151        }
5152
5153        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5154                -100, callerWillRestart, true, doit, evenPersistent,
5155                name == null ? ("stop user " + userId) : ("stop " + name));
5156
5157        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5158            if (!doit) {
5159                return true;
5160            }
5161            didSomething = true;
5162        }
5163
5164        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5165            if (!doit) {
5166                return true;
5167            }
5168            didSomething = true;
5169        }
5170
5171        if (name == null) {
5172            // Remove all sticky broadcasts from this user.
5173            mStickyBroadcasts.remove(userId);
5174        }
5175
5176        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5177        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5178                userId, providers)) {
5179            if (!doit) {
5180                return true;
5181            }
5182            didSomething = true;
5183        }
5184        N = providers.size();
5185        for (i=0; i<N; i++) {
5186            removeDyingProviderLocked(null, providers.get(i), true);
5187        }
5188
5189        // Remove transient permissions granted from/to this package/user
5190        removeUriPermissionsForPackageLocked(name, userId, false);
5191
5192        if (name == null || uninstalling) {
5193            // Remove pending intents.  For now we only do this when force
5194            // stopping users, because we have some problems when doing this
5195            // for packages -- app widgets are not currently cleaned up for
5196            // such packages, so they can be left with bad pending intents.
5197            if (mIntentSenderRecords.size() > 0) {
5198                Iterator<WeakReference<PendingIntentRecord>> it
5199                        = mIntentSenderRecords.values().iterator();
5200                while (it.hasNext()) {
5201                    WeakReference<PendingIntentRecord> wpir = it.next();
5202                    if (wpir == null) {
5203                        it.remove();
5204                        continue;
5205                    }
5206                    PendingIntentRecord pir = wpir.get();
5207                    if (pir == null) {
5208                        it.remove();
5209                        continue;
5210                    }
5211                    if (name == null) {
5212                        // Stopping user, remove all objects for the user.
5213                        if (pir.key.userId != userId) {
5214                            // Not the same user, skip it.
5215                            continue;
5216                        }
5217                    } else {
5218                        if (UserHandle.getAppId(pir.uid) != appId) {
5219                            // Different app id, skip it.
5220                            continue;
5221                        }
5222                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5223                            // Different user, skip it.
5224                            continue;
5225                        }
5226                        if (!pir.key.packageName.equals(name)) {
5227                            // Different package, skip it.
5228                            continue;
5229                        }
5230                    }
5231                    if (!doit) {
5232                        return true;
5233                    }
5234                    didSomething = true;
5235                    it.remove();
5236                    pir.canceled = true;
5237                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5238                        pir.key.activity.pendingResults.remove(pir.ref);
5239                    }
5240                }
5241            }
5242        }
5243
5244        if (doit) {
5245            if (purgeCache && name != null) {
5246                AttributeCache ac = AttributeCache.instance();
5247                if (ac != null) {
5248                    ac.removePackage(name);
5249                }
5250            }
5251            if (mBooted) {
5252                mStackSupervisor.resumeTopActivitiesLocked();
5253                mStackSupervisor.scheduleIdleLocked();
5254            }
5255        }
5256
5257        return didSomething;
5258    }
5259
5260    private final boolean removeProcessLocked(ProcessRecord app,
5261            boolean callerWillRestart, boolean allowRestart, String reason) {
5262        final String name = app.processName;
5263        final int uid = app.uid;
5264        if (DEBUG_PROCESSES) Slog.d(
5265            TAG, "Force removing proc " + app.toShortString() + " (" + name
5266            + "/" + uid + ")");
5267
5268        mProcessNames.remove(name, uid);
5269        mIsolatedProcesses.remove(app.uid);
5270        if (mHeavyWeightProcess == app) {
5271            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5272                    mHeavyWeightProcess.userId, 0));
5273            mHeavyWeightProcess = null;
5274        }
5275        boolean needRestart = false;
5276        if (app.pid > 0 && app.pid != MY_PID) {
5277            int pid = app.pid;
5278            synchronized (mPidsSelfLocked) {
5279                mPidsSelfLocked.remove(pid);
5280                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5281            }
5282            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5283            if (app.isolated) {
5284                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5285            }
5286            app.kill(reason, true);
5287            handleAppDiedLocked(app, true, allowRestart);
5288            removeLruProcessLocked(app);
5289
5290            if (app.persistent && !app.isolated) {
5291                if (!callerWillRestart) {
5292                    addAppLocked(app.info, false, null /* ABI override */);
5293                } else {
5294                    needRestart = true;
5295                }
5296            }
5297        } else {
5298            mRemovedProcesses.add(app);
5299        }
5300
5301        return needRestart;
5302    }
5303
5304    private final void processStartTimedOutLocked(ProcessRecord app) {
5305        final int pid = app.pid;
5306        boolean gone = false;
5307        synchronized (mPidsSelfLocked) {
5308            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5309            if (knownApp != null && knownApp.thread == null) {
5310                mPidsSelfLocked.remove(pid);
5311                gone = true;
5312            }
5313        }
5314
5315        if (gone) {
5316            Slog.w(TAG, "Process " + app + " failed to attach");
5317            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5318                    pid, app.uid, app.processName);
5319            mProcessNames.remove(app.processName, app.uid);
5320            mIsolatedProcesses.remove(app.uid);
5321            if (mHeavyWeightProcess == app) {
5322                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5323                        mHeavyWeightProcess.userId, 0));
5324                mHeavyWeightProcess = null;
5325            }
5326            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5327            if (app.isolated) {
5328                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5329            }
5330            // Take care of any launching providers waiting for this process.
5331            checkAppInLaunchingProvidersLocked(app, true);
5332            // Take care of any services that are waiting for the process.
5333            mServices.processStartTimedOutLocked(app);
5334            app.kill("start timeout", true);
5335            removeLruProcessLocked(app);
5336            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5337                Slog.w(TAG, "Unattached app died before backup, skipping");
5338                try {
5339                    IBackupManager bm = IBackupManager.Stub.asInterface(
5340                            ServiceManager.getService(Context.BACKUP_SERVICE));
5341                    bm.agentDisconnected(app.info.packageName);
5342                } catch (RemoteException e) {
5343                    // Can't happen; the backup manager is local
5344                }
5345            }
5346            if (isPendingBroadcastProcessLocked(pid)) {
5347                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5348                skipPendingBroadcastLocked(pid);
5349            }
5350        } else {
5351            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5352        }
5353    }
5354
5355    private final boolean attachApplicationLocked(IApplicationThread thread,
5356            int pid) {
5357
5358        // Find the application record that is being attached...  either via
5359        // the pid if we are running in multiple processes, or just pull the
5360        // next app record if we are emulating process with anonymous threads.
5361        ProcessRecord app;
5362        if (pid != MY_PID && pid >= 0) {
5363            synchronized (mPidsSelfLocked) {
5364                app = mPidsSelfLocked.get(pid);
5365            }
5366        } else {
5367            app = null;
5368        }
5369
5370        if (app == null) {
5371            Slog.w(TAG, "No pending application record for pid " + pid
5372                    + " (IApplicationThread " + thread + "); dropping process");
5373            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5374            if (pid > 0 && pid != MY_PID) {
5375                Process.killProcessQuiet(pid);
5376                //TODO: Process.killProcessGroup(app.info.uid, pid);
5377            } else {
5378                try {
5379                    thread.scheduleExit();
5380                } catch (Exception e) {
5381                    // Ignore exceptions.
5382                }
5383            }
5384            return false;
5385        }
5386
5387        // If this application record is still attached to a previous
5388        // process, clean it up now.
5389        if (app.thread != null) {
5390            handleAppDiedLocked(app, true, true);
5391        }
5392
5393        // Tell the process all about itself.
5394
5395        if (localLOGV) Slog.v(
5396                TAG, "Binding process pid " + pid + " to record " + app);
5397
5398        final String processName = app.processName;
5399        try {
5400            AppDeathRecipient adr = new AppDeathRecipient(
5401                    app, pid, thread);
5402            thread.asBinder().linkToDeath(adr, 0);
5403            app.deathRecipient = adr;
5404        } catch (RemoteException e) {
5405            app.resetPackageList(mProcessStats);
5406            startProcessLocked(app, "link fail", processName);
5407            return false;
5408        }
5409
5410        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5411
5412        app.makeActive(thread, mProcessStats);
5413        app.curAdj = app.setAdj = -100;
5414        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5415        app.forcingToForeground = null;
5416        updateProcessForegroundLocked(app, false, false);
5417        app.hasShownUi = false;
5418        app.debugging = false;
5419        app.cached = false;
5420        app.killedByAm = false;
5421
5422        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5423
5424        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5425        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5426
5427        if (!normalMode) {
5428            Slog.i(TAG, "Launching preboot mode app: " + app);
5429        }
5430
5431        if (localLOGV) Slog.v(
5432            TAG, "New app record " + app
5433            + " thread=" + thread.asBinder() + " pid=" + pid);
5434        try {
5435            int testMode = IApplicationThread.DEBUG_OFF;
5436            if (mDebugApp != null && mDebugApp.equals(processName)) {
5437                testMode = mWaitForDebugger
5438                    ? IApplicationThread.DEBUG_WAIT
5439                    : IApplicationThread.DEBUG_ON;
5440                app.debugging = true;
5441                if (mDebugTransient) {
5442                    mDebugApp = mOrigDebugApp;
5443                    mWaitForDebugger = mOrigWaitForDebugger;
5444                }
5445            }
5446            String profileFile = app.instrumentationProfileFile;
5447            ParcelFileDescriptor profileFd = null;
5448            int samplingInterval = 0;
5449            boolean profileAutoStop = false;
5450            if (mProfileApp != null && mProfileApp.equals(processName)) {
5451                mProfileProc = app;
5452                profileFile = mProfileFile;
5453                profileFd = mProfileFd;
5454                samplingInterval = mSamplingInterval;
5455                profileAutoStop = mAutoStopProfiler;
5456            }
5457            boolean enableOpenGlTrace = false;
5458            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5459                enableOpenGlTrace = true;
5460                mOpenGlTraceApp = null;
5461            }
5462
5463            // If the app is being launched for restore or full backup, set it up specially
5464            boolean isRestrictedBackupMode = false;
5465            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5466                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5467                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5468                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5469            }
5470
5471            ensurePackageDexOpt(app.instrumentationInfo != null
5472                    ? app.instrumentationInfo.packageName
5473                    : app.info.packageName);
5474            if (app.instrumentationClass != null) {
5475                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5476            }
5477            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5478                    + processName + " with config " + mConfiguration);
5479            ApplicationInfo appInfo = app.instrumentationInfo != null
5480                    ? app.instrumentationInfo : app.info;
5481            app.compat = compatibilityInfoForPackageLocked(appInfo);
5482            if (profileFd != null) {
5483                profileFd = profileFd.dup();
5484            }
5485            ProfilerInfo profilerInfo = profileFile == null ? null
5486                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5487            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5488                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5489                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5490                    isRestrictedBackupMode || !normalMode, app.persistent,
5491                    new Configuration(mConfiguration), app.compat,
5492                    getCommonServicesLocked(app.isolated),
5493                    mCoreSettingsObserver.getCoreSettingsLocked());
5494            updateLruProcessLocked(app, false, null);
5495            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5496        } catch (Exception e) {
5497            // todo: Yikes!  What should we do?  For now we will try to
5498            // start another process, but that could easily get us in
5499            // an infinite loop of restarting processes...
5500            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5501
5502            app.resetPackageList(mProcessStats);
5503            app.unlinkDeathRecipient();
5504            startProcessLocked(app, "bind fail", processName);
5505            return false;
5506        }
5507
5508        // Remove this record from the list of starting applications.
5509        mPersistentStartingProcesses.remove(app);
5510        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5511                "Attach application locked removing on hold: " + app);
5512        mProcessesOnHold.remove(app);
5513
5514        boolean badApp = false;
5515        boolean didSomething = false;
5516
5517        // See if the top visible activity is waiting to run in this process...
5518        if (normalMode) {
5519            try {
5520                if (mStackSupervisor.attachApplicationLocked(app)) {
5521                    didSomething = true;
5522                }
5523            } catch (Exception e) {
5524                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5525                badApp = true;
5526            }
5527        }
5528
5529        // Find any services that should be running in this process...
5530        if (!badApp) {
5531            try {
5532                didSomething |= mServices.attachApplicationLocked(app, processName);
5533            } catch (Exception e) {
5534                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5535                badApp = true;
5536            }
5537        }
5538
5539        // Check if a next-broadcast receiver is in this process...
5540        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5541            try {
5542                didSomething |= sendPendingBroadcastsLocked(app);
5543            } catch (Exception e) {
5544                // If the app died trying to launch the receiver we declare it 'bad'
5545                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
5546                badApp = true;
5547            }
5548        }
5549
5550        // Check whether the next backup agent is in this process...
5551        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5552            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5553            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5554            try {
5555                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5556                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5557                        mBackupTarget.backupMode);
5558            } catch (Exception e) {
5559                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
5560                badApp = true;
5561            }
5562        }
5563
5564        if (badApp) {
5565            app.kill("error during init", true);
5566            handleAppDiedLocked(app, false, true);
5567            return false;
5568        }
5569
5570        if (!didSomething) {
5571            updateOomAdjLocked();
5572        }
5573
5574        return true;
5575    }
5576
5577    @Override
5578    public final void attachApplication(IApplicationThread thread) {
5579        synchronized (this) {
5580            int callingPid = Binder.getCallingPid();
5581            final long origId = Binder.clearCallingIdentity();
5582            attachApplicationLocked(thread, callingPid);
5583            Binder.restoreCallingIdentity(origId);
5584        }
5585    }
5586
5587    @Override
5588    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5589        final long origId = Binder.clearCallingIdentity();
5590        synchronized (this) {
5591            ActivityStack stack = ActivityRecord.getStackLocked(token);
5592            if (stack != null) {
5593                ActivityRecord r =
5594                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5595                if (stopProfiling) {
5596                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5597                        try {
5598                            mProfileFd.close();
5599                        } catch (IOException e) {
5600                        }
5601                        clearProfilerLocked();
5602                    }
5603                }
5604            }
5605        }
5606        Binder.restoreCallingIdentity(origId);
5607    }
5608
5609    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
5610        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
5611                finishBooting? 1 : 0, enableScreen ? 1 : 0));
5612    }
5613
5614    void enableScreenAfterBoot() {
5615        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5616                SystemClock.uptimeMillis());
5617        mWindowManager.enableScreenAfterBoot();
5618
5619        synchronized (this) {
5620            updateEventDispatchingLocked();
5621        }
5622    }
5623
5624    @Override
5625    public void showBootMessage(final CharSequence msg, final boolean always) {
5626        if (Binder.getCallingUid() != Process.myUid()) {
5627            // These days only the core system can call this, so apps can't get in
5628            // the way of what we show about running them.
5629        }
5630        mWindowManager.showBootMessage(msg, always);
5631    }
5632
5633    @Override
5634    public void keyguardWaitingForActivityDrawn() {
5635        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5636        final long token = Binder.clearCallingIdentity();
5637        try {
5638            synchronized (this) {
5639                if (DEBUG_LOCKSCREEN) logLockScreen("");
5640                mWindowManager.keyguardWaitingForActivityDrawn();
5641                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
5642                    mLockScreenShown = LOCK_SCREEN_LEAVING;
5643                    updateSleepIfNeededLocked();
5644                }
5645            }
5646        } finally {
5647            Binder.restoreCallingIdentity(token);
5648        }
5649    }
5650
5651    final void finishBooting() {
5652        synchronized (this) {
5653            if (!mBootAnimationComplete) {
5654                mCallFinishBooting = true;
5655                return;
5656            }
5657            mCallFinishBooting = false;
5658        }
5659
5660        ArraySet<String> completedIsas = new ArraySet<String>();
5661        for (String abi : Build.SUPPORTED_ABIS) {
5662            Process.establishZygoteConnectionForAbi(abi);
5663            final String instructionSet = VMRuntime.getInstructionSet(abi);
5664            if (!completedIsas.contains(instructionSet)) {
5665                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
5666                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
5667                }
5668                completedIsas.add(instructionSet);
5669            }
5670        }
5671
5672        IntentFilter pkgFilter = new IntentFilter();
5673        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5674        pkgFilter.addDataScheme("package");
5675        mContext.registerReceiver(new BroadcastReceiver() {
5676            @Override
5677            public void onReceive(Context context, Intent intent) {
5678                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5679                if (pkgs != null) {
5680                    for (String pkg : pkgs) {
5681                        synchronized (ActivityManagerService.this) {
5682                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
5683                                    0, "finished booting")) {
5684                                setResultCode(Activity.RESULT_OK);
5685                                return;
5686                            }
5687                        }
5688                    }
5689                }
5690            }
5691        }, pkgFilter);
5692
5693        // Let system services know.
5694        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5695
5696        synchronized (this) {
5697            // Ensure that any processes we had put on hold are now started
5698            // up.
5699            final int NP = mProcessesOnHold.size();
5700            if (NP > 0) {
5701                ArrayList<ProcessRecord> procs =
5702                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5703                for (int ip=0; ip<NP; ip++) {
5704                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5705                            + procs.get(ip));
5706                    startProcessLocked(procs.get(ip), "on-hold", null);
5707                }
5708            }
5709
5710            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5711                // Start looking for apps that are abusing wake locks.
5712                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5713                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5714                // Tell anyone interested that we are done booting!
5715                SystemProperties.set("sys.boot_completed", "1");
5716
5717                // And trigger dev.bootcomplete if we are not showing encryption progress
5718                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
5719                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
5720                    SystemProperties.set("dev.bootcomplete", "1");
5721                }
5722                for (int i=0; i<mStartedUsers.size(); i++) {
5723                    UserStartedState uss = mStartedUsers.valueAt(i);
5724                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5725                        uss.mState = UserStartedState.STATE_RUNNING;
5726                        final int userId = mStartedUsers.keyAt(i);
5727                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5728                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5729                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5730                        broadcastIntentLocked(null, null, intent, null,
5731                                new IIntentReceiver.Stub() {
5732                                    @Override
5733                                    public void performReceive(Intent intent, int resultCode,
5734                                            String data, Bundle extras, boolean ordered,
5735                                            boolean sticky, int sendingUser) {
5736                                        synchronized (ActivityManagerService.this) {
5737                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5738                                                    true, false);
5739                                        }
5740                                    }
5741                                },
5742                                0, null, null,
5743                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5744                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5745                                userId);
5746                    }
5747                }
5748                scheduleStartProfilesLocked();
5749            }
5750        }
5751    }
5752
5753    @Override
5754    public void bootAnimationComplete() {
5755        final boolean callFinishBooting;
5756        synchronized (this) {
5757            callFinishBooting = mCallFinishBooting;
5758            mBootAnimationComplete = true;
5759        }
5760        if (callFinishBooting) {
5761            finishBooting();
5762        }
5763    }
5764
5765    @Override
5766    public void systemBackupRestored() {
5767        synchronized (this) {
5768            if (mSystemReady) {
5769                mTaskPersister.restoreTasksFromOtherDeviceLocked();
5770            } else {
5771                Slog.w(TAG, "System backup restored before system is ready");
5772            }
5773        }
5774    }
5775
5776    final void ensureBootCompleted() {
5777        boolean booting;
5778        boolean enableScreen;
5779        synchronized (this) {
5780            booting = mBooting;
5781            mBooting = false;
5782            enableScreen = !mBooted;
5783            mBooted = true;
5784        }
5785
5786        if (booting) {
5787            finishBooting();
5788        }
5789
5790        if (enableScreen) {
5791            enableScreenAfterBoot();
5792        }
5793    }
5794
5795    @Override
5796    public final void activityResumed(IBinder token) {
5797        final long origId = Binder.clearCallingIdentity();
5798        synchronized(this) {
5799            ActivityStack stack = ActivityRecord.getStackLocked(token);
5800            if (stack != null) {
5801                ActivityRecord.activityResumedLocked(token);
5802            }
5803        }
5804        Binder.restoreCallingIdentity(origId);
5805    }
5806
5807    @Override
5808    public final void activityPaused(IBinder token) {
5809        final long origId = Binder.clearCallingIdentity();
5810        synchronized(this) {
5811            ActivityStack stack = ActivityRecord.getStackLocked(token);
5812            if (stack != null) {
5813                stack.activityPausedLocked(token, false);
5814            }
5815        }
5816        Binder.restoreCallingIdentity(origId);
5817    }
5818
5819    @Override
5820    public final void activityStopped(IBinder token, Bundle icicle,
5821            PersistableBundle persistentState, CharSequence description) {
5822        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5823
5824        // Refuse possible leaked file descriptors
5825        if (icicle != null && icicle.hasFileDescriptors()) {
5826            throw new IllegalArgumentException("File descriptors passed in Bundle");
5827        }
5828
5829        final long origId = Binder.clearCallingIdentity();
5830
5831        synchronized (this) {
5832            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5833            if (r != null) {
5834                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5835            }
5836        }
5837
5838        trimApplications();
5839
5840        Binder.restoreCallingIdentity(origId);
5841    }
5842
5843    @Override
5844    public final void activityDestroyed(IBinder token) {
5845        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5846        synchronized (this) {
5847            ActivityStack stack = ActivityRecord.getStackLocked(token);
5848            if (stack != null) {
5849                stack.activityDestroyedLocked(token, "activityDestroyed");
5850            }
5851        }
5852    }
5853
5854    @Override
5855    public final void backgroundResourcesReleased(IBinder token) {
5856        final long origId = Binder.clearCallingIdentity();
5857        try {
5858            synchronized (this) {
5859                ActivityStack stack = ActivityRecord.getStackLocked(token);
5860                if (stack != null) {
5861                    stack.backgroundResourcesReleased();
5862                }
5863            }
5864        } finally {
5865            Binder.restoreCallingIdentity(origId);
5866        }
5867    }
5868
5869    @Override
5870    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5871        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5872    }
5873
5874    @Override
5875    public final void notifyEnterAnimationComplete(IBinder token) {
5876        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5877    }
5878
5879    @Override
5880    public String getCallingPackage(IBinder token) {
5881        synchronized (this) {
5882            ActivityRecord r = getCallingRecordLocked(token);
5883            return r != null ? r.info.packageName : null;
5884        }
5885    }
5886
5887    @Override
5888    public ComponentName getCallingActivity(IBinder token) {
5889        synchronized (this) {
5890            ActivityRecord r = getCallingRecordLocked(token);
5891            return r != null ? r.intent.getComponent() : null;
5892        }
5893    }
5894
5895    private ActivityRecord getCallingRecordLocked(IBinder token) {
5896        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5897        if (r == null) {
5898            return null;
5899        }
5900        return r.resultTo;
5901    }
5902
5903    @Override
5904    public ComponentName getActivityClassForToken(IBinder token) {
5905        synchronized(this) {
5906            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5907            if (r == null) {
5908                return null;
5909            }
5910            return r.intent.getComponent();
5911        }
5912    }
5913
5914    @Override
5915    public String getPackageForToken(IBinder token) {
5916        synchronized(this) {
5917            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5918            if (r == null) {
5919                return null;
5920            }
5921            return r.packageName;
5922        }
5923    }
5924
5925    @Override
5926    public IIntentSender getIntentSender(int type,
5927            String packageName, IBinder token, String resultWho,
5928            int requestCode, Intent[] intents, String[] resolvedTypes,
5929            int flags, Bundle options, int userId) {
5930        enforceNotIsolatedCaller("getIntentSender");
5931        // Refuse possible leaked file descriptors
5932        if (intents != null) {
5933            if (intents.length < 1) {
5934                throw new IllegalArgumentException("Intents array length must be >= 1");
5935            }
5936            for (int i=0; i<intents.length; i++) {
5937                Intent intent = intents[i];
5938                if (intent != null) {
5939                    if (intent.hasFileDescriptors()) {
5940                        throw new IllegalArgumentException("File descriptors passed in Intent");
5941                    }
5942                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5943                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5944                        throw new IllegalArgumentException(
5945                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5946                    }
5947                    intents[i] = new Intent(intent);
5948                }
5949            }
5950            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5951                throw new IllegalArgumentException(
5952                        "Intent array length does not match resolvedTypes length");
5953            }
5954        }
5955        if (options != null) {
5956            if (options.hasFileDescriptors()) {
5957                throw new IllegalArgumentException("File descriptors passed in options");
5958            }
5959        }
5960
5961        synchronized(this) {
5962            int callingUid = Binder.getCallingUid();
5963            int origUserId = userId;
5964            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5965                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5966                    ALLOW_NON_FULL, "getIntentSender", null);
5967            if (origUserId == UserHandle.USER_CURRENT) {
5968                // We don't want to evaluate this until the pending intent is
5969                // actually executed.  However, we do want to always do the
5970                // security checking for it above.
5971                userId = UserHandle.USER_CURRENT;
5972            }
5973            try {
5974                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5975                    int uid = AppGlobals.getPackageManager()
5976                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5977                    if (!UserHandle.isSameApp(callingUid, uid)) {
5978                        String msg = "Permission Denial: getIntentSender() from pid="
5979                            + Binder.getCallingPid()
5980                            + ", uid=" + Binder.getCallingUid()
5981                            + ", (need uid=" + uid + ")"
5982                            + " is not allowed to send as package " + packageName;
5983                        Slog.w(TAG, msg);
5984                        throw new SecurityException(msg);
5985                    }
5986                }
5987
5988                return getIntentSenderLocked(type, packageName, callingUid, userId,
5989                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5990
5991            } catch (RemoteException e) {
5992                throw new SecurityException(e);
5993            }
5994        }
5995    }
5996
5997    IIntentSender getIntentSenderLocked(int type, String packageName,
5998            int callingUid, int userId, IBinder token, String resultWho,
5999            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6000            Bundle options) {
6001        if (DEBUG_MU)
6002            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6003        ActivityRecord activity = null;
6004        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6005            activity = ActivityRecord.isInStackLocked(token);
6006            if (activity == null) {
6007                return null;
6008            }
6009            if (activity.finishing) {
6010                return null;
6011            }
6012        }
6013
6014        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6015        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6016        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6017        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6018                |PendingIntent.FLAG_UPDATE_CURRENT);
6019
6020        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6021                type, packageName, activity, resultWho,
6022                requestCode, intents, resolvedTypes, flags, options, userId);
6023        WeakReference<PendingIntentRecord> ref;
6024        ref = mIntentSenderRecords.get(key);
6025        PendingIntentRecord rec = ref != null ? ref.get() : null;
6026        if (rec != null) {
6027            if (!cancelCurrent) {
6028                if (updateCurrent) {
6029                    if (rec.key.requestIntent != null) {
6030                        rec.key.requestIntent.replaceExtras(intents != null ?
6031                                intents[intents.length - 1] : null);
6032                    }
6033                    if (intents != null) {
6034                        intents[intents.length-1] = rec.key.requestIntent;
6035                        rec.key.allIntents = intents;
6036                        rec.key.allResolvedTypes = resolvedTypes;
6037                    } else {
6038                        rec.key.allIntents = null;
6039                        rec.key.allResolvedTypes = null;
6040                    }
6041                }
6042                return rec;
6043            }
6044            rec.canceled = true;
6045            mIntentSenderRecords.remove(key);
6046        }
6047        if (noCreate) {
6048            return rec;
6049        }
6050        rec = new PendingIntentRecord(this, key, callingUid);
6051        mIntentSenderRecords.put(key, rec.ref);
6052        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6053            if (activity.pendingResults == null) {
6054                activity.pendingResults
6055                        = new HashSet<WeakReference<PendingIntentRecord>>();
6056            }
6057            activity.pendingResults.add(rec.ref);
6058        }
6059        return rec;
6060    }
6061
6062    @Override
6063    public void cancelIntentSender(IIntentSender sender) {
6064        if (!(sender instanceof PendingIntentRecord)) {
6065            return;
6066        }
6067        synchronized(this) {
6068            PendingIntentRecord rec = (PendingIntentRecord)sender;
6069            try {
6070                int uid = AppGlobals.getPackageManager()
6071                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6072                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6073                    String msg = "Permission Denial: cancelIntentSender() from pid="
6074                        + Binder.getCallingPid()
6075                        + ", uid=" + Binder.getCallingUid()
6076                        + " is not allowed to cancel packges "
6077                        + rec.key.packageName;
6078                    Slog.w(TAG, msg);
6079                    throw new SecurityException(msg);
6080                }
6081            } catch (RemoteException e) {
6082                throw new SecurityException(e);
6083            }
6084            cancelIntentSenderLocked(rec, true);
6085        }
6086    }
6087
6088    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6089        rec.canceled = true;
6090        mIntentSenderRecords.remove(rec.key);
6091        if (cleanActivity && rec.key.activity != null) {
6092            rec.key.activity.pendingResults.remove(rec.ref);
6093        }
6094    }
6095
6096    @Override
6097    public String getPackageForIntentSender(IIntentSender pendingResult) {
6098        if (!(pendingResult instanceof PendingIntentRecord)) {
6099            return null;
6100        }
6101        try {
6102            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6103            return res.key.packageName;
6104        } catch (ClassCastException e) {
6105        }
6106        return null;
6107    }
6108
6109    @Override
6110    public int getUidForIntentSender(IIntentSender sender) {
6111        if (sender instanceof PendingIntentRecord) {
6112            try {
6113                PendingIntentRecord res = (PendingIntentRecord)sender;
6114                return res.uid;
6115            } catch (ClassCastException e) {
6116            }
6117        }
6118        return -1;
6119    }
6120
6121    @Override
6122    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6123        if (!(pendingResult instanceof PendingIntentRecord)) {
6124            return false;
6125        }
6126        try {
6127            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6128            if (res.key.allIntents == null) {
6129                return false;
6130            }
6131            for (int i=0; i<res.key.allIntents.length; i++) {
6132                Intent intent = res.key.allIntents[i];
6133                if (intent.getPackage() != null && intent.getComponent() != null) {
6134                    return false;
6135                }
6136            }
6137            return true;
6138        } catch (ClassCastException e) {
6139        }
6140        return false;
6141    }
6142
6143    @Override
6144    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6145        if (!(pendingResult instanceof PendingIntentRecord)) {
6146            return false;
6147        }
6148        try {
6149            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6150            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6151                return true;
6152            }
6153            return false;
6154        } catch (ClassCastException e) {
6155        }
6156        return false;
6157    }
6158
6159    @Override
6160    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6161        if (!(pendingResult instanceof PendingIntentRecord)) {
6162            return null;
6163        }
6164        try {
6165            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6166            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6167        } catch (ClassCastException e) {
6168        }
6169        return null;
6170    }
6171
6172    @Override
6173    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6174        if (!(pendingResult instanceof PendingIntentRecord)) {
6175            return null;
6176        }
6177        try {
6178            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6179            Intent intent = res.key.requestIntent;
6180            if (intent != null) {
6181                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6182                        || res.lastTagPrefix.equals(prefix))) {
6183                    return res.lastTag;
6184                }
6185                res.lastTagPrefix = prefix;
6186                StringBuilder sb = new StringBuilder(128);
6187                if (prefix != null) {
6188                    sb.append(prefix);
6189                }
6190                if (intent.getAction() != null) {
6191                    sb.append(intent.getAction());
6192                } else if (intent.getComponent() != null) {
6193                    intent.getComponent().appendShortString(sb);
6194                } else {
6195                    sb.append("?");
6196                }
6197                return res.lastTag = sb.toString();
6198            }
6199        } catch (ClassCastException e) {
6200        }
6201        return null;
6202    }
6203
6204    @Override
6205    public void setProcessLimit(int max) {
6206        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6207                "setProcessLimit()");
6208        synchronized (this) {
6209            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6210            mProcessLimitOverride = max;
6211        }
6212        trimApplications();
6213    }
6214
6215    @Override
6216    public int getProcessLimit() {
6217        synchronized (this) {
6218            return mProcessLimitOverride;
6219        }
6220    }
6221
6222    void foregroundTokenDied(ForegroundToken token) {
6223        synchronized (ActivityManagerService.this) {
6224            synchronized (mPidsSelfLocked) {
6225                ForegroundToken cur
6226                    = mForegroundProcesses.get(token.pid);
6227                if (cur != token) {
6228                    return;
6229                }
6230                mForegroundProcesses.remove(token.pid);
6231                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6232                if (pr == null) {
6233                    return;
6234                }
6235                pr.forcingToForeground = null;
6236                updateProcessForegroundLocked(pr, false, false);
6237            }
6238            updateOomAdjLocked();
6239        }
6240    }
6241
6242    @Override
6243    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6244        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6245                "setProcessForeground()");
6246        synchronized(this) {
6247            boolean changed = false;
6248
6249            synchronized (mPidsSelfLocked) {
6250                ProcessRecord pr = mPidsSelfLocked.get(pid);
6251                if (pr == null && isForeground) {
6252                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6253                    return;
6254                }
6255                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6256                if (oldToken != null) {
6257                    oldToken.token.unlinkToDeath(oldToken, 0);
6258                    mForegroundProcesses.remove(pid);
6259                    if (pr != null) {
6260                        pr.forcingToForeground = null;
6261                    }
6262                    changed = true;
6263                }
6264                if (isForeground && token != null) {
6265                    ForegroundToken newToken = new ForegroundToken() {
6266                        @Override
6267                        public void binderDied() {
6268                            foregroundTokenDied(this);
6269                        }
6270                    };
6271                    newToken.pid = pid;
6272                    newToken.token = token;
6273                    try {
6274                        token.linkToDeath(newToken, 0);
6275                        mForegroundProcesses.put(pid, newToken);
6276                        pr.forcingToForeground = token;
6277                        changed = true;
6278                    } catch (RemoteException e) {
6279                        // If the process died while doing this, we will later
6280                        // do the cleanup with the process death link.
6281                    }
6282                }
6283            }
6284
6285            if (changed) {
6286                updateOomAdjLocked();
6287            }
6288        }
6289    }
6290
6291    // =========================================================
6292    // PERMISSIONS
6293    // =========================================================
6294
6295    static class PermissionController extends IPermissionController.Stub {
6296        ActivityManagerService mActivityManagerService;
6297        PermissionController(ActivityManagerService activityManagerService) {
6298            mActivityManagerService = activityManagerService;
6299        }
6300
6301        @Override
6302        public boolean checkPermission(String permission, int pid, int uid) {
6303            return mActivityManagerService.checkPermission(permission, pid,
6304                    uid) == PackageManager.PERMISSION_GRANTED;
6305        }
6306    }
6307
6308    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6309        @Override
6310        public int checkComponentPermission(String permission, int pid, int uid,
6311                int owningUid, boolean exported) {
6312            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6313                    owningUid, exported);
6314        }
6315
6316        @Override
6317        public Object getAMSLock() {
6318            return ActivityManagerService.this;
6319        }
6320    }
6321
6322    /**
6323     * This can be called with or without the global lock held.
6324     */
6325    int checkComponentPermission(String permission, int pid, int uid,
6326            int owningUid, boolean exported) {
6327        if (pid == MY_PID) {
6328            return PackageManager.PERMISSION_GRANTED;
6329        }
6330        return ActivityManager.checkComponentPermission(permission, uid,
6331                owningUid, exported);
6332    }
6333
6334    /**
6335     * As the only public entry point for permissions checking, this method
6336     * can enforce the semantic that requesting a check on a null global
6337     * permission is automatically denied.  (Internally a null permission
6338     * string is used when calling {@link #checkComponentPermission} in cases
6339     * when only uid-based security is needed.)
6340     *
6341     * This can be called with or without the global lock held.
6342     */
6343    @Override
6344    public int checkPermission(String permission, int pid, int uid) {
6345        if (permission == null) {
6346            return PackageManager.PERMISSION_DENIED;
6347        }
6348        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6349    }
6350
6351    @Override
6352    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6353        if (permission == null) {
6354            return PackageManager.PERMISSION_DENIED;
6355        }
6356
6357        // We might be performing an operation on behalf of an indirect binder
6358        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6359        // client identity accordingly before proceeding.
6360        Identity tlsIdentity = sCallerIdentity.get();
6361        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6362            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6363                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6364            uid = tlsIdentity.uid;
6365            pid = tlsIdentity.pid;
6366        }
6367
6368        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6369    }
6370
6371    /**
6372     * Binder IPC calls go through the public entry point.
6373     * This can be called with or without the global lock held.
6374     */
6375    int checkCallingPermission(String permission) {
6376        return checkPermission(permission,
6377                Binder.getCallingPid(),
6378                UserHandle.getAppId(Binder.getCallingUid()));
6379    }
6380
6381    /**
6382     * This can be called with or without the global lock held.
6383     */
6384    void enforceCallingPermission(String permission, String func) {
6385        if (checkCallingPermission(permission)
6386                == PackageManager.PERMISSION_GRANTED) {
6387            return;
6388        }
6389
6390        String msg = "Permission Denial: " + func + " from pid="
6391                + Binder.getCallingPid()
6392                + ", uid=" + Binder.getCallingUid()
6393                + " requires " + permission;
6394        Slog.w(TAG, msg);
6395        throw new SecurityException(msg);
6396    }
6397
6398    /**
6399     * Determine if UID is holding permissions required to access {@link Uri} in
6400     * the given {@link ProviderInfo}. Final permission checking is always done
6401     * in {@link ContentProvider}.
6402     */
6403    private final boolean checkHoldingPermissionsLocked(
6404            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6405        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6406                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6407        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6408            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6409                    != PERMISSION_GRANTED) {
6410                return false;
6411            }
6412        }
6413        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6414    }
6415
6416    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6417            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6418        if (pi.applicationInfo.uid == uid) {
6419            return true;
6420        } else if (!pi.exported) {
6421            return false;
6422        }
6423
6424        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6425        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6426        try {
6427            // check if target holds top-level <provider> permissions
6428            if (!readMet && pi.readPermission != null && considerUidPermissions
6429                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6430                readMet = true;
6431            }
6432            if (!writeMet && pi.writePermission != null && considerUidPermissions
6433                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6434                writeMet = true;
6435            }
6436
6437            // track if unprotected read/write is allowed; any denied
6438            // <path-permission> below removes this ability
6439            boolean allowDefaultRead = pi.readPermission == null;
6440            boolean allowDefaultWrite = pi.writePermission == null;
6441
6442            // check if target holds any <path-permission> that match uri
6443            final PathPermission[] pps = pi.pathPermissions;
6444            if (pps != null) {
6445                final String path = grantUri.uri.getPath();
6446                int i = pps.length;
6447                while (i > 0 && (!readMet || !writeMet)) {
6448                    i--;
6449                    PathPermission pp = pps[i];
6450                    if (pp.match(path)) {
6451                        if (!readMet) {
6452                            final String pprperm = pp.getReadPermission();
6453                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6454                                    + pprperm + " for " + pp.getPath()
6455                                    + ": match=" + pp.match(path)
6456                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6457                            if (pprperm != null) {
6458                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6459                                        == PERMISSION_GRANTED) {
6460                                    readMet = true;
6461                                } else {
6462                                    allowDefaultRead = false;
6463                                }
6464                            }
6465                        }
6466                        if (!writeMet) {
6467                            final String ppwperm = pp.getWritePermission();
6468                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6469                                    + ppwperm + " for " + pp.getPath()
6470                                    + ": match=" + pp.match(path)
6471                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6472                            if (ppwperm != null) {
6473                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6474                                        == PERMISSION_GRANTED) {
6475                                    writeMet = true;
6476                                } else {
6477                                    allowDefaultWrite = false;
6478                                }
6479                            }
6480                        }
6481                    }
6482                }
6483            }
6484
6485            // grant unprotected <provider> read/write, if not blocked by
6486            // <path-permission> above
6487            if (allowDefaultRead) readMet = true;
6488            if (allowDefaultWrite) writeMet = true;
6489
6490        } catch (RemoteException e) {
6491            return false;
6492        }
6493
6494        return readMet && writeMet;
6495    }
6496
6497    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6498        ProviderInfo pi = null;
6499        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6500        if (cpr != null) {
6501            pi = cpr.info;
6502        } else {
6503            try {
6504                pi = AppGlobals.getPackageManager().resolveContentProvider(
6505                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6506            } catch (RemoteException ex) {
6507            }
6508        }
6509        return pi;
6510    }
6511
6512    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6513        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6514        if (targetUris != null) {
6515            return targetUris.get(grantUri);
6516        }
6517        return null;
6518    }
6519
6520    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6521            String targetPkg, int targetUid, GrantUri grantUri) {
6522        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6523        if (targetUris == null) {
6524            targetUris = Maps.newArrayMap();
6525            mGrantedUriPermissions.put(targetUid, targetUris);
6526        }
6527
6528        UriPermission perm = targetUris.get(grantUri);
6529        if (perm == null) {
6530            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6531            targetUris.put(grantUri, perm);
6532        }
6533
6534        return perm;
6535    }
6536
6537    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6538            final int modeFlags) {
6539        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6540        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6541                : UriPermission.STRENGTH_OWNED;
6542
6543        // Root gets to do everything.
6544        if (uid == 0) {
6545            return true;
6546        }
6547
6548        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6549        if (perms == null) return false;
6550
6551        // First look for exact match
6552        final UriPermission exactPerm = perms.get(grantUri);
6553        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6554            return true;
6555        }
6556
6557        // No exact match, look for prefixes
6558        final int N = perms.size();
6559        for (int i = 0; i < N; i++) {
6560            final UriPermission perm = perms.valueAt(i);
6561            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6562                    && perm.getStrength(modeFlags) >= minStrength) {
6563                return true;
6564            }
6565        }
6566
6567        return false;
6568    }
6569
6570    /**
6571     * @param uri This uri must NOT contain an embedded userId.
6572     * @param userId The userId in which the uri is to be resolved.
6573     */
6574    @Override
6575    public int checkUriPermission(Uri uri, int pid, int uid,
6576            final int modeFlags, int userId, IBinder callerToken) {
6577        enforceNotIsolatedCaller("checkUriPermission");
6578
6579        // Another redirected-binder-call permissions check as in
6580        // {@link checkPermissionWithToken}.
6581        Identity tlsIdentity = sCallerIdentity.get();
6582        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6583            uid = tlsIdentity.uid;
6584            pid = tlsIdentity.pid;
6585        }
6586
6587        // Our own process gets to do everything.
6588        if (pid == MY_PID) {
6589            return PackageManager.PERMISSION_GRANTED;
6590        }
6591        synchronized (this) {
6592            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6593                    ? PackageManager.PERMISSION_GRANTED
6594                    : PackageManager.PERMISSION_DENIED;
6595        }
6596    }
6597
6598    /**
6599     * Check if the targetPkg can be granted permission to access uri by
6600     * the callingUid using the given modeFlags.  Throws a security exception
6601     * if callingUid is not allowed to do this.  Returns the uid of the target
6602     * if the URI permission grant should be performed; returns -1 if it is not
6603     * needed (for example targetPkg already has permission to access the URI).
6604     * If you already know the uid of the target, you can supply it in
6605     * lastTargetUid else set that to -1.
6606     */
6607    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6608            final int modeFlags, int lastTargetUid) {
6609        if (!Intent.isAccessUriMode(modeFlags)) {
6610            return -1;
6611        }
6612
6613        if (targetPkg != null) {
6614            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6615                    "Checking grant " + targetPkg + " permission to " + grantUri);
6616        }
6617
6618        final IPackageManager pm = AppGlobals.getPackageManager();
6619
6620        // If this is not a content: uri, we can't do anything with it.
6621        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6622            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6623                    "Can't grant URI permission for non-content URI: " + grantUri);
6624            return -1;
6625        }
6626
6627        final String authority = grantUri.uri.getAuthority();
6628        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6629        if (pi == null) {
6630            Slog.w(TAG, "No content provider found for permission check: " +
6631                    grantUri.uri.toSafeString());
6632            return -1;
6633        }
6634
6635        int targetUid = lastTargetUid;
6636        if (targetUid < 0 && targetPkg != null) {
6637            try {
6638                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6639                if (targetUid < 0) {
6640                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6641                            "Can't grant URI permission no uid for: " + targetPkg);
6642                    return -1;
6643                }
6644            } catch (RemoteException ex) {
6645                return -1;
6646            }
6647        }
6648
6649        if (targetUid >= 0) {
6650            // First...  does the target actually need this permission?
6651            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6652                // No need to grant the target this permission.
6653                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6654                        "Target " + targetPkg + " already has full permission to " + grantUri);
6655                return -1;
6656            }
6657        } else {
6658            // First...  there is no target package, so can anyone access it?
6659            boolean allowed = pi.exported;
6660            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6661                if (pi.readPermission != null) {
6662                    allowed = false;
6663                }
6664            }
6665            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6666                if (pi.writePermission != null) {
6667                    allowed = false;
6668                }
6669            }
6670            if (allowed) {
6671                return -1;
6672            }
6673        }
6674
6675        /* There is a special cross user grant if:
6676         * - The target is on another user.
6677         * - Apps on the current user can access the uri without any uid permissions.
6678         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6679         * grant uri permissions.
6680         */
6681        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6682                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6683                modeFlags, false /*without considering the uid permissions*/);
6684
6685        // Second...  is the provider allowing granting of URI permissions?
6686        if (!specialCrossUserGrant) {
6687            if (!pi.grantUriPermissions) {
6688                throw new SecurityException("Provider " + pi.packageName
6689                        + "/" + pi.name
6690                        + " does not allow granting of Uri permissions (uri "
6691                        + grantUri + ")");
6692            }
6693            if (pi.uriPermissionPatterns != null) {
6694                final int N = pi.uriPermissionPatterns.length;
6695                boolean allowed = false;
6696                for (int i=0; i<N; i++) {
6697                    if (pi.uriPermissionPatterns[i] != null
6698                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6699                        allowed = true;
6700                        break;
6701                    }
6702                }
6703                if (!allowed) {
6704                    throw new SecurityException("Provider " + pi.packageName
6705                            + "/" + pi.name
6706                            + " does not allow granting of permission to path of Uri "
6707                            + grantUri);
6708                }
6709            }
6710        }
6711
6712        // Third...  does the caller itself have permission to access
6713        // this uri?
6714        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6715            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6716                // Require they hold a strong enough Uri permission
6717                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6718                    throw new SecurityException("Uid " + callingUid
6719                            + " does not have permission to uri " + grantUri);
6720                }
6721            }
6722        }
6723        return targetUid;
6724    }
6725
6726    /**
6727     * @param uri This uri must NOT contain an embedded userId.
6728     * @param userId The userId in which the uri is to be resolved.
6729     */
6730    @Override
6731    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6732            final int modeFlags, int userId) {
6733        enforceNotIsolatedCaller("checkGrantUriPermission");
6734        synchronized(this) {
6735            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6736                    new GrantUri(userId, uri, false), modeFlags, -1);
6737        }
6738    }
6739
6740    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6741            final int modeFlags, UriPermissionOwner owner) {
6742        if (!Intent.isAccessUriMode(modeFlags)) {
6743            return;
6744        }
6745
6746        // So here we are: the caller has the assumed permission
6747        // to the uri, and the target doesn't.  Let's now give this to
6748        // the target.
6749
6750        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6751                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6752
6753        final String authority = grantUri.uri.getAuthority();
6754        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6755        if (pi == null) {
6756            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6757            return;
6758        }
6759
6760        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6761            grantUri.prefix = true;
6762        }
6763        final UriPermission perm = findOrCreateUriPermissionLocked(
6764                pi.packageName, targetPkg, targetUid, grantUri);
6765        perm.grantModes(modeFlags, owner);
6766    }
6767
6768    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6769            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6770        if (targetPkg == null) {
6771            throw new NullPointerException("targetPkg");
6772        }
6773        int targetUid;
6774        final IPackageManager pm = AppGlobals.getPackageManager();
6775        try {
6776            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6777        } catch (RemoteException ex) {
6778            return;
6779        }
6780
6781        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6782                targetUid);
6783        if (targetUid < 0) {
6784            return;
6785        }
6786
6787        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6788                owner);
6789    }
6790
6791    static class NeededUriGrants extends ArrayList<GrantUri> {
6792        final String targetPkg;
6793        final int targetUid;
6794        final int flags;
6795
6796        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6797            this.targetPkg = targetPkg;
6798            this.targetUid = targetUid;
6799            this.flags = flags;
6800        }
6801    }
6802
6803    /**
6804     * Like checkGrantUriPermissionLocked, but takes an Intent.
6805     */
6806    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6807            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6808        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6809                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6810                + " clip=" + (intent != null ? intent.getClipData() : null)
6811                + " from " + intent + "; flags=0x"
6812                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6813
6814        if (targetPkg == null) {
6815            throw new NullPointerException("targetPkg");
6816        }
6817
6818        if (intent == null) {
6819            return null;
6820        }
6821        Uri data = intent.getData();
6822        ClipData clip = intent.getClipData();
6823        if (data == null && clip == null) {
6824            return null;
6825        }
6826        // Default userId for uris in the intent (if they don't specify it themselves)
6827        int contentUserHint = intent.getContentUserHint();
6828        if (contentUserHint == UserHandle.USER_CURRENT) {
6829            contentUserHint = UserHandle.getUserId(callingUid);
6830        }
6831        final IPackageManager pm = AppGlobals.getPackageManager();
6832        int targetUid;
6833        if (needed != null) {
6834            targetUid = needed.targetUid;
6835        } else {
6836            try {
6837                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6838            } catch (RemoteException ex) {
6839                return null;
6840            }
6841            if (targetUid < 0) {
6842                if (DEBUG_URI_PERMISSION) {
6843                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6844                            + " on user " + targetUserId);
6845                }
6846                return null;
6847            }
6848        }
6849        if (data != null) {
6850            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6851            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6852                    targetUid);
6853            if (targetUid > 0) {
6854                if (needed == null) {
6855                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6856                }
6857                needed.add(grantUri);
6858            }
6859        }
6860        if (clip != null) {
6861            for (int i=0; i<clip.getItemCount(); i++) {
6862                Uri uri = clip.getItemAt(i).getUri();
6863                if (uri != null) {
6864                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6865                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6866                            targetUid);
6867                    if (targetUid > 0) {
6868                        if (needed == null) {
6869                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6870                        }
6871                        needed.add(grantUri);
6872                    }
6873                } else {
6874                    Intent clipIntent = clip.getItemAt(i).getIntent();
6875                    if (clipIntent != null) {
6876                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6877                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6878                        if (newNeeded != null) {
6879                            needed = newNeeded;
6880                        }
6881                    }
6882                }
6883            }
6884        }
6885
6886        return needed;
6887    }
6888
6889    /**
6890     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6891     */
6892    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6893            UriPermissionOwner owner) {
6894        if (needed != null) {
6895            for (int i=0; i<needed.size(); i++) {
6896                GrantUri grantUri = needed.get(i);
6897                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6898                        grantUri, needed.flags, owner);
6899            }
6900        }
6901    }
6902
6903    void grantUriPermissionFromIntentLocked(int callingUid,
6904            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6905        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6906                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6907        if (needed == null) {
6908            return;
6909        }
6910
6911        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6912    }
6913
6914    /**
6915     * @param uri This uri must NOT contain an embedded userId.
6916     * @param userId The userId in which the uri is to be resolved.
6917     */
6918    @Override
6919    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6920            final int modeFlags, int userId) {
6921        enforceNotIsolatedCaller("grantUriPermission");
6922        GrantUri grantUri = new GrantUri(userId, uri, false);
6923        synchronized(this) {
6924            final ProcessRecord r = getRecordForAppLocked(caller);
6925            if (r == null) {
6926                throw new SecurityException("Unable to find app for caller "
6927                        + caller
6928                        + " when granting permission to uri " + grantUri);
6929            }
6930            if (targetPkg == null) {
6931                throw new IllegalArgumentException("null target");
6932            }
6933            if (grantUri == null) {
6934                throw new IllegalArgumentException("null uri");
6935            }
6936
6937            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6938                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6939                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6940                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6941
6942            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6943                    UserHandle.getUserId(r.uid));
6944        }
6945    }
6946
6947    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6948        if (perm.modeFlags == 0) {
6949            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6950                    perm.targetUid);
6951            if (perms != null) {
6952                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6953                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6954
6955                perms.remove(perm.uri);
6956                if (perms.isEmpty()) {
6957                    mGrantedUriPermissions.remove(perm.targetUid);
6958                }
6959            }
6960        }
6961    }
6962
6963    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6964        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6965
6966        final IPackageManager pm = AppGlobals.getPackageManager();
6967        final String authority = grantUri.uri.getAuthority();
6968        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6969        if (pi == null) {
6970            Slog.w(TAG, "No content provider found for permission revoke: "
6971                    + grantUri.toSafeString());
6972            return;
6973        }
6974
6975        // Does the caller have this permission on the URI?
6976        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6977            // If they don't have direct access to the URI, then revoke any
6978            // ownerless URI permissions that have been granted to them.
6979            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6980            if (perms != null) {
6981                boolean persistChanged = false;
6982                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6983                    final UriPermission perm = it.next();
6984                    if (perm.uri.sourceUserId == grantUri.sourceUserId
6985                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6986                        if (DEBUG_URI_PERMISSION)
6987                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
6988                                    " permission to " + perm.uri);
6989                        persistChanged |= perm.revokeModes(
6990                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
6991                        if (perm.modeFlags == 0) {
6992                            it.remove();
6993                        }
6994                    }
6995                }
6996                if (perms.isEmpty()) {
6997                    mGrantedUriPermissions.remove(callingUid);
6998                }
6999                if (persistChanged) {
7000                    schedulePersistUriGrants();
7001                }
7002            }
7003            return;
7004        }
7005
7006        boolean persistChanged = false;
7007
7008        // Go through all of the permissions and remove any that match.
7009        int N = mGrantedUriPermissions.size();
7010        for (int i = 0; i < N; i++) {
7011            final int targetUid = mGrantedUriPermissions.keyAt(i);
7012            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7013
7014            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7015                final UriPermission perm = it.next();
7016                if (perm.uri.sourceUserId == grantUri.sourceUserId
7017                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7018                    if (DEBUG_URI_PERMISSION)
7019                        Slog.v(TAG,
7020                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7021                    persistChanged |= perm.revokeModes(
7022                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7023                    if (perm.modeFlags == 0) {
7024                        it.remove();
7025                    }
7026                }
7027            }
7028
7029            if (perms.isEmpty()) {
7030                mGrantedUriPermissions.remove(targetUid);
7031                N--;
7032                i--;
7033            }
7034        }
7035
7036        if (persistChanged) {
7037            schedulePersistUriGrants();
7038        }
7039    }
7040
7041    /**
7042     * @param uri This uri must NOT contain an embedded userId.
7043     * @param userId The userId in which the uri is to be resolved.
7044     */
7045    @Override
7046    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7047            int userId) {
7048        enforceNotIsolatedCaller("revokeUriPermission");
7049        synchronized(this) {
7050            final ProcessRecord r = getRecordForAppLocked(caller);
7051            if (r == null) {
7052                throw new SecurityException("Unable to find app for caller "
7053                        + caller
7054                        + " when revoking permission to uri " + uri);
7055            }
7056            if (uri == null) {
7057                Slog.w(TAG, "revokeUriPermission: null uri");
7058                return;
7059            }
7060
7061            if (!Intent.isAccessUriMode(modeFlags)) {
7062                return;
7063            }
7064
7065            final String authority = uri.getAuthority();
7066            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7067            if (pi == null) {
7068                Slog.w(TAG, "No content provider found for permission revoke: "
7069                        + uri.toSafeString());
7070                return;
7071            }
7072
7073            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7074        }
7075    }
7076
7077    /**
7078     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7079     * given package.
7080     *
7081     * @param packageName Package name to match, or {@code null} to apply to all
7082     *            packages.
7083     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7084     *            to all users.
7085     * @param persistable If persistable grants should be removed.
7086     */
7087    private void removeUriPermissionsForPackageLocked(
7088            String packageName, int userHandle, boolean persistable) {
7089        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7090            throw new IllegalArgumentException("Must narrow by either package or user");
7091        }
7092
7093        boolean persistChanged = false;
7094
7095        int N = mGrantedUriPermissions.size();
7096        for (int i = 0; i < N; i++) {
7097            final int targetUid = mGrantedUriPermissions.keyAt(i);
7098            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7099
7100            // Only inspect grants matching user
7101            if (userHandle == UserHandle.USER_ALL
7102                    || userHandle == UserHandle.getUserId(targetUid)) {
7103                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7104                    final UriPermission perm = it.next();
7105
7106                    // Only inspect grants matching package
7107                    if (packageName == null || perm.sourcePkg.equals(packageName)
7108                            || perm.targetPkg.equals(packageName)) {
7109                        persistChanged |= perm.revokeModes(persistable
7110                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7111
7112                        // Only remove when no modes remain; any persisted grants
7113                        // will keep this alive.
7114                        if (perm.modeFlags == 0) {
7115                            it.remove();
7116                        }
7117                    }
7118                }
7119
7120                if (perms.isEmpty()) {
7121                    mGrantedUriPermissions.remove(targetUid);
7122                    N--;
7123                    i--;
7124                }
7125            }
7126        }
7127
7128        if (persistChanged) {
7129            schedulePersistUriGrants();
7130        }
7131    }
7132
7133    @Override
7134    public IBinder newUriPermissionOwner(String name) {
7135        enforceNotIsolatedCaller("newUriPermissionOwner");
7136        synchronized(this) {
7137            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7138            return owner.getExternalTokenLocked();
7139        }
7140    }
7141
7142    /**
7143     * @param uri This uri must NOT contain an embedded userId.
7144     * @param sourceUserId The userId in which the uri is to be resolved.
7145     * @param targetUserId The userId of the app that receives the grant.
7146     */
7147    @Override
7148    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7149            final int modeFlags, int sourceUserId, int targetUserId) {
7150        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7151                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7152        synchronized(this) {
7153            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7154            if (owner == null) {
7155                throw new IllegalArgumentException("Unknown owner: " + token);
7156            }
7157            if (fromUid != Binder.getCallingUid()) {
7158                if (Binder.getCallingUid() != Process.myUid()) {
7159                    // Only system code can grant URI permissions on behalf
7160                    // of other users.
7161                    throw new SecurityException("nice try");
7162                }
7163            }
7164            if (targetPkg == null) {
7165                throw new IllegalArgumentException("null target");
7166            }
7167            if (uri == null) {
7168                throw new IllegalArgumentException("null uri");
7169            }
7170
7171            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7172                    modeFlags, owner, targetUserId);
7173        }
7174    }
7175
7176    /**
7177     * @param uri This uri must NOT contain an embedded userId.
7178     * @param userId The userId in which the uri is to be resolved.
7179     */
7180    @Override
7181    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7182        synchronized(this) {
7183            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7184            if (owner == null) {
7185                throw new IllegalArgumentException("Unknown owner: " + token);
7186            }
7187
7188            if (uri == null) {
7189                owner.removeUriPermissionsLocked(mode);
7190            } else {
7191                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7192            }
7193        }
7194    }
7195
7196    private void schedulePersistUriGrants() {
7197        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7198            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7199                    10 * DateUtils.SECOND_IN_MILLIS);
7200        }
7201    }
7202
7203    private void writeGrantedUriPermissions() {
7204        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7205
7206        // Snapshot permissions so we can persist without lock
7207        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7208        synchronized (this) {
7209            final int size = mGrantedUriPermissions.size();
7210            for (int i = 0; i < size; i++) {
7211                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7212                for (UriPermission perm : perms.values()) {
7213                    if (perm.persistedModeFlags != 0) {
7214                        persist.add(perm.snapshot());
7215                    }
7216                }
7217            }
7218        }
7219
7220        FileOutputStream fos = null;
7221        try {
7222            fos = mGrantFile.startWrite();
7223
7224            XmlSerializer out = new FastXmlSerializer();
7225            out.setOutput(fos, "utf-8");
7226            out.startDocument(null, true);
7227            out.startTag(null, TAG_URI_GRANTS);
7228            for (UriPermission.Snapshot perm : persist) {
7229                out.startTag(null, TAG_URI_GRANT);
7230                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7231                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7232                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7233                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7234                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7235                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7236                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7237                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7238                out.endTag(null, TAG_URI_GRANT);
7239            }
7240            out.endTag(null, TAG_URI_GRANTS);
7241            out.endDocument();
7242
7243            mGrantFile.finishWrite(fos);
7244        } catch (IOException e) {
7245            if (fos != null) {
7246                mGrantFile.failWrite(fos);
7247            }
7248        }
7249    }
7250
7251    private void readGrantedUriPermissionsLocked() {
7252        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7253
7254        final long now = System.currentTimeMillis();
7255
7256        FileInputStream fis = null;
7257        try {
7258            fis = mGrantFile.openRead();
7259            final XmlPullParser in = Xml.newPullParser();
7260            in.setInput(fis, null);
7261
7262            int type;
7263            while ((type = in.next()) != END_DOCUMENT) {
7264                final String tag = in.getName();
7265                if (type == START_TAG) {
7266                    if (TAG_URI_GRANT.equals(tag)) {
7267                        final int sourceUserId;
7268                        final int targetUserId;
7269                        final int userHandle = readIntAttribute(in,
7270                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7271                        if (userHandle != UserHandle.USER_NULL) {
7272                            // For backwards compatibility.
7273                            sourceUserId = userHandle;
7274                            targetUserId = userHandle;
7275                        } else {
7276                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7277                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7278                        }
7279                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7280                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7281                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7282                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7283                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7284                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7285
7286                        // Sanity check that provider still belongs to source package
7287                        final ProviderInfo pi = getProviderInfoLocked(
7288                                uri.getAuthority(), sourceUserId);
7289                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7290                            int targetUid = -1;
7291                            try {
7292                                targetUid = AppGlobals.getPackageManager()
7293                                        .getPackageUid(targetPkg, targetUserId);
7294                            } catch (RemoteException e) {
7295                            }
7296                            if (targetUid != -1) {
7297                                final UriPermission perm = findOrCreateUriPermissionLocked(
7298                                        sourcePkg, targetPkg, targetUid,
7299                                        new GrantUri(sourceUserId, uri, prefix));
7300                                perm.initPersistedModes(modeFlags, createdTime);
7301                            }
7302                        } else {
7303                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7304                                    + " but instead found " + pi);
7305                        }
7306                    }
7307                }
7308            }
7309        } catch (FileNotFoundException e) {
7310            // Missing grants is okay
7311        } catch (IOException e) {
7312            Slog.wtf(TAG, "Failed reading Uri grants", e);
7313        } catch (XmlPullParserException e) {
7314            Slog.wtf(TAG, "Failed reading Uri grants", e);
7315        } finally {
7316            IoUtils.closeQuietly(fis);
7317        }
7318    }
7319
7320    /**
7321     * @param uri This uri must NOT contain an embedded userId.
7322     * @param userId The userId in which the uri is to be resolved.
7323     */
7324    @Override
7325    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7326        enforceNotIsolatedCaller("takePersistableUriPermission");
7327
7328        Preconditions.checkFlagsArgument(modeFlags,
7329                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7330
7331        synchronized (this) {
7332            final int callingUid = Binder.getCallingUid();
7333            boolean persistChanged = false;
7334            GrantUri grantUri = new GrantUri(userId, uri, false);
7335
7336            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7337                    new GrantUri(userId, uri, false));
7338            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7339                    new GrantUri(userId, uri, true));
7340
7341            final boolean exactValid = (exactPerm != null)
7342                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7343            final boolean prefixValid = (prefixPerm != null)
7344                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7345
7346            if (!(exactValid || prefixValid)) {
7347                throw new SecurityException("No persistable permission grants found for UID "
7348                        + callingUid + " and Uri " + grantUri.toSafeString());
7349            }
7350
7351            if (exactValid) {
7352                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7353            }
7354            if (prefixValid) {
7355                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7356            }
7357
7358            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7359
7360            if (persistChanged) {
7361                schedulePersistUriGrants();
7362            }
7363        }
7364    }
7365
7366    /**
7367     * @param uri This uri must NOT contain an embedded userId.
7368     * @param userId The userId in which the uri is to be resolved.
7369     */
7370    @Override
7371    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7372        enforceNotIsolatedCaller("releasePersistableUriPermission");
7373
7374        Preconditions.checkFlagsArgument(modeFlags,
7375                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7376
7377        synchronized (this) {
7378            final int callingUid = Binder.getCallingUid();
7379            boolean persistChanged = false;
7380
7381            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7382                    new GrantUri(userId, uri, false));
7383            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7384                    new GrantUri(userId, uri, true));
7385            if (exactPerm == null && prefixPerm == null) {
7386                throw new SecurityException("No permission grants found for UID " + callingUid
7387                        + " and Uri " + uri.toSafeString());
7388            }
7389
7390            if (exactPerm != null) {
7391                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7392                removeUriPermissionIfNeededLocked(exactPerm);
7393            }
7394            if (prefixPerm != null) {
7395                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7396                removeUriPermissionIfNeededLocked(prefixPerm);
7397            }
7398
7399            if (persistChanged) {
7400                schedulePersistUriGrants();
7401            }
7402        }
7403    }
7404
7405    /**
7406     * Prune any older {@link UriPermission} for the given UID until outstanding
7407     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7408     *
7409     * @return if any mutations occured that require persisting.
7410     */
7411    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7412        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7413        if (perms == null) return false;
7414        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7415
7416        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7417        for (UriPermission perm : perms.values()) {
7418            if (perm.persistedModeFlags != 0) {
7419                persisted.add(perm);
7420            }
7421        }
7422
7423        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7424        if (trimCount <= 0) return false;
7425
7426        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7427        for (int i = 0; i < trimCount; i++) {
7428            final UriPermission perm = persisted.get(i);
7429
7430            if (DEBUG_URI_PERMISSION) {
7431                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7432            }
7433
7434            perm.releasePersistableModes(~0);
7435            removeUriPermissionIfNeededLocked(perm);
7436        }
7437
7438        return true;
7439    }
7440
7441    @Override
7442    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7443            String packageName, boolean incoming) {
7444        enforceNotIsolatedCaller("getPersistedUriPermissions");
7445        Preconditions.checkNotNull(packageName, "packageName");
7446
7447        final int callingUid = Binder.getCallingUid();
7448        final IPackageManager pm = AppGlobals.getPackageManager();
7449        try {
7450            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7451            if (packageUid != callingUid) {
7452                throw new SecurityException(
7453                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7454            }
7455        } catch (RemoteException e) {
7456            throw new SecurityException("Failed to verify package name ownership");
7457        }
7458
7459        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7460        synchronized (this) {
7461            if (incoming) {
7462                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7463                        callingUid);
7464                if (perms == null) {
7465                    Slog.w(TAG, "No permission grants found for " + packageName);
7466                } else {
7467                    for (UriPermission perm : perms.values()) {
7468                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7469                            result.add(perm.buildPersistedPublicApiObject());
7470                        }
7471                    }
7472                }
7473            } else {
7474                final int size = mGrantedUriPermissions.size();
7475                for (int i = 0; i < size; i++) {
7476                    final ArrayMap<GrantUri, UriPermission> perms =
7477                            mGrantedUriPermissions.valueAt(i);
7478                    for (UriPermission perm : perms.values()) {
7479                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7480                            result.add(perm.buildPersistedPublicApiObject());
7481                        }
7482                    }
7483                }
7484            }
7485        }
7486        return new ParceledListSlice<android.content.UriPermission>(result);
7487    }
7488
7489    @Override
7490    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7491        synchronized (this) {
7492            ProcessRecord app =
7493                who != null ? getRecordForAppLocked(who) : null;
7494            if (app == null) return;
7495
7496            Message msg = Message.obtain();
7497            msg.what = WAIT_FOR_DEBUGGER_MSG;
7498            msg.obj = app;
7499            msg.arg1 = waiting ? 1 : 0;
7500            mHandler.sendMessage(msg);
7501        }
7502    }
7503
7504    @Override
7505    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7506        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7507        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7508        outInfo.availMem = Process.getFreeMemory();
7509        outInfo.totalMem = Process.getTotalMemory();
7510        outInfo.threshold = homeAppMem;
7511        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7512        outInfo.hiddenAppThreshold = cachedAppMem;
7513        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7514                ProcessList.SERVICE_ADJ);
7515        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7516                ProcessList.VISIBLE_APP_ADJ);
7517        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7518                ProcessList.FOREGROUND_APP_ADJ);
7519    }
7520
7521    // =========================================================
7522    // TASK MANAGEMENT
7523    // =========================================================
7524
7525    @Override
7526    public List<IAppTask> getAppTasks(String callingPackage) {
7527        int callingUid = Binder.getCallingUid();
7528        long ident = Binder.clearCallingIdentity();
7529
7530        synchronized(this) {
7531            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7532            try {
7533                if (localLOGV) Slog.v(TAG, "getAppTasks");
7534
7535                final int N = mRecentTasks.size();
7536                for (int i = 0; i < N; i++) {
7537                    TaskRecord tr = mRecentTasks.get(i);
7538                    // Skip tasks that do not match the caller.  We don't need to verify
7539                    // callingPackage, because we are also limiting to callingUid and know
7540                    // that will limit to the correct security sandbox.
7541                    if (tr.effectiveUid != callingUid) {
7542                        continue;
7543                    }
7544                    Intent intent = tr.getBaseIntent();
7545                    if (intent == null ||
7546                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7547                        continue;
7548                    }
7549                    ActivityManager.RecentTaskInfo taskInfo =
7550                            createRecentTaskInfoFromTaskRecord(tr);
7551                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7552                    list.add(taskImpl);
7553                }
7554            } finally {
7555                Binder.restoreCallingIdentity(ident);
7556            }
7557            return list;
7558        }
7559    }
7560
7561    @Override
7562    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7563        final int callingUid = Binder.getCallingUid();
7564        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7565
7566        synchronized(this) {
7567            if (localLOGV) Slog.v(
7568                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7569
7570            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
7571                    callingUid);
7572
7573            // TODO: Improve with MRU list from all ActivityStacks.
7574            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7575        }
7576
7577        return list;
7578    }
7579
7580    /**
7581     * Creates a new RecentTaskInfo from a TaskRecord.
7582     */
7583    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7584        // Update the task description to reflect any changes in the task stack
7585        tr.updateTaskDescription();
7586
7587        // Compose the recent task info
7588        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7589        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
7590        rti.persistentId = tr.taskId;
7591        rti.baseIntent = new Intent(tr.getBaseIntent());
7592        rti.origActivity = tr.origActivity;
7593        rti.description = tr.lastDescription;
7594        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7595        rti.userId = tr.userId;
7596        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7597        rti.firstActiveTime = tr.firstActiveTime;
7598        rti.lastActiveTime = tr.lastActiveTime;
7599        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7600        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7601        return rti;
7602    }
7603
7604    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
7605        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
7606                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
7607        if (!allowed) {
7608            if (checkPermission(android.Manifest.permission.GET_TASKS,
7609                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
7610                // Temporary compatibility: some existing apps on the system image may
7611                // still be requesting the old permission and not switched to the new
7612                // one; if so, we'll still allow them full access.  This means we need
7613                // to see if they are holding the old permission and are a system app.
7614                try {
7615                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
7616                        allowed = true;
7617                        Slog.w(TAG, caller + ": caller " + callingUid
7618                                + " is using old GET_TASKS but privileged; allowing");
7619                    }
7620                } catch (RemoteException e) {
7621                }
7622            }
7623        }
7624        if (!allowed) {
7625            Slog.w(TAG, caller + ": caller " + callingUid
7626                    + " does not hold GET_TASKS; limiting output");
7627        }
7628        return allowed;
7629    }
7630
7631    @Override
7632    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7633        final int callingUid = Binder.getCallingUid();
7634        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7635                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7636
7637        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7638        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7639        synchronized (this) {
7640            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
7641                    callingUid);
7642            final boolean detailed = checkCallingPermission(
7643                    android.Manifest.permission.GET_DETAILED_TASKS)
7644                    == PackageManager.PERMISSION_GRANTED;
7645
7646            final int N = mRecentTasks.size();
7647            ArrayList<ActivityManager.RecentTaskInfo> res
7648                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7649                            maxNum < N ? maxNum : N);
7650
7651            final Set<Integer> includedUsers;
7652            if (includeProfiles) {
7653                includedUsers = getProfileIdsLocked(userId);
7654            } else {
7655                includedUsers = new HashSet<Integer>();
7656            }
7657            includedUsers.add(Integer.valueOf(userId));
7658
7659            for (int i=0; i<N && maxNum > 0; i++) {
7660                TaskRecord tr = mRecentTasks.get(i);
7661                // Only add calling user or related users recent tasks
7662                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
7663                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
7664                    continue;
7665                }
7666
7667                // Return the entry if desired by the caller.  We always return
7668                // the first entry, because callers always expect this to be the
7669                // foreground app.  We may filter others if the caller has
7670                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7671                // we should exclude the entry.
7672
7673                if (i == 0
7674                        || withExcluded
7675                        || (tr.intent == null)
7676                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7677                                == 0)) {
7678                    if (!allowed) {
7679                        // If the caller doesn't have the GET_TASKS permission, then only
7680                        // allow them to see a small subset of tasks -- their own and home.
7681                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
7682                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
7683                            continue;
7684                        }
7685                    }
7686                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
7687                        if (tr.stack != null && tr.stack.isHomeStack()) {
7688                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
7689                            continue;
7690                        }
7691                    }
7692                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7693                        // Don't include auto remove tasks that are finished or finishing.
7694                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
7695                                + tr);
7696                        continue;
7697                    }
7698                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
7699                            && !tr.isAvailable) {
7700                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
7701                        continue;
7702                    }
7703
7704                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7705                    if (!detailed) {
7706                        rti.baseIntent.replaceExtras((Bundle)null);
7707                    }
7708
7709                    res.add(rti);
7710                    maxNum--;
7711                }
7712            }
7713            return res;
7714        }
7715    }
7716
7717    @Override
7718    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7719        synchronized (this) {
7720            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7721                    "getTaskThumbnail()");
7722            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
7723            if (tr != null) {
7724                return tr.getTaskThumbnailLocked();
7725            }
7726        }
7727        return null;
7728    }
7729
7730    @Override
7731    public int addAppTask(IBinder activityToken, Intent intent,
7732            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
7733        final int callingUid = Binder.getCallingUid();
7734        final long callingIdent = Binder.clearCallingIdentity();
7735
7736        try {
7737            synchronized (this) {
7738                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
7739                if (r == null) {
7740                    throw new IllegalArgumentException("Activity does not exist; token="
7741                            + activityToken);
7742                }
7743                ComponentName comp = intent.getComponent();
7744                if (comp == null) {
7745                    throw new IllegalArgumentException("Intent " + intent
7746                            + " must specify explicit component");
7747                }
7748                if (thumbnail.getWidth() != mThumbnailWidth
7749                        || thumbnail.getHeight() != mThumbnailHeight) {
7750                    throw new IllegalArgumentException("Bad thumbnail size: got "
7751                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
7752                            + mThumbnailWidth + "x" + mThumbnailHeight);
7753                }
7754                if (intent.getSelector() != null) {
7755                    intent.setSelector(null);
7756                }
7757                if (intent.getSourceBounds() != null) {
7758                    intent.setSourceBounds(null);
7759                }
7760                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
7761                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
7762                        // The caller has added this as an auto-remove task...  that makes no
7763                        // sense, so turn off auto-remove.
7764                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
7765                    }
7766                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
7767                    // Must be a new task.
7768                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7769                }
7770                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
7771                    mLastAddedTaskActivity = null;
7772                }
7773                ActivityInfo ainfo = mLastAddedTaskActivity;
7774                if (ainfo == null) {
7775                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
7776                            comp, 0, UserHandle.getUserId(callingUid));
7777                    if (ainfo.applicationInfo.uid != callingUid) {
7778                        throw new SecurityException(
7779                                "Can't add task for another application: target uid="
7780                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
7781                    }
7782                }
7783
7784                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
7785                        intent, description);
7786
7787                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
7788                if (trimIdx >= 0) {
7789                    // If this would have caused a trim, then we'll abort because that
7790                    // means it would be added at the end of the list but then just removed.
7791                    return INVALID_TASK_ID;
7792                }
7793
7794                final int N = mRecentTasks.size();
7795                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
7796                    final TaskRecord tr = mRecentTasks.remove(N - 1);
7797                    tr.removedFromRecents();
7798                }
7799
7800                task.inRecents = true;
7801                mRecentTasks.add(task);
7802                r.task.stack.addTask(task, false, false);
7803
7804                task.setLastThumbnail(thumbnail);
7805                task.freeLastThumbnail();
7806
7807                return task.taskId;
7808            }
7809        } finally {
7810            Binder.restoreCallingIdentity(callingIdent);
7811        }
7812    }
7813
7814    @Override
7815    public Point getAppTaskThumbnailSize() {
7816        synchronized (this) {
7817            return new Point(mThumbnailWidth,  mThumbnailHeight);
7818        }
7819    }
7820
7821    @Override
7822    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7823        synchronized (this) {
7824            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7825            if (r != null) {
7826                r.setTaskDescription(td);
7827                r.task.updateTaskDescription();
7828            }
7829        }
7830    }
7831
7832    @Override
7833    public Bitmap getTaskDescriptionIcon(String filename) {
7834        if (!FileUtils.isValidExtFilename(filename)
7835                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
7836            throw new IllegalArgumentException("Bad filename: " + filename);
7837        }
7838        return mTaskPersister.getTaskDescriptionIcon(filename);
7839    }
7840
7841    @Override
7842    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
7843            throws RemoteException {
7844        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
7845                opts.getCustomInPlaceResId() == 0) {
7846            throw new IllegalArgumentException("Expected in-place ActivityOption " +
7847                    "with valid animation");
7848        }
7849        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
7850        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
7851                opts.getCustomInPlaceResId());
7852        mWindowManager.executeAppTransition();
7853    }
7854
7855    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
7856        mRecentTasks.remove(tr);
7857        tr.removedFromRecents();
7858        ComponentName component = tr.getBaseIntent().getComponent();
7859        if (component == null) {
7860            Slog.w(TAG, "No component for base intent of task: " + tr);
7861            return;
7862        }
7863
7864        if (!killProcess) {
7865            return;
7866        }
7867
7868        // Determine if the process(es) for this task should be killed.
7869        final String pkg = component.getPackageName();
7870        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
7871        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7872        for (int i = 0; i < pmap.size(); i++) {
7873
7874            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7875            for (int j = 0; j < uids.size(); j++) {
7876                ProcessRecord proc = uids.valueAt(j);
7877                if (proc.userId != tr.userId) {
7878                    // Don't kill process for a different user.
7879                    continue;
7880                }
7881                if (proc == mHomeProcess) {
7882                    // Don't kill the home process along with tasks from the same package.
7883                    continue;
7884                }
7885                if (!proc.pkgList.containsKey(pkg)) {
7886                    // Don't kill process that is not associated with this task.
7887                    continue;
7888                }
7889
7890                for (int k = 0; k < proc.activities.size(); k++) {
7891                    TaskRecord otherTask = proc.activities.get(k).task;
7892                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
7893                        // Don't kill process(es) that has an activity in a different task that is
7894                        // also in recents.
7895                        return;
7896                    }
7897                }
7898
7899                // Add process to kill list.
7900                procsToKill.add(proc);
7901            }
7902        }
7903
7904        // Find any running services associated with this app and stop if needed.
7905        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
7906
7907        // Kill the running processes.
7908        for (int i = 0; i < procsToKill.size(); i++) {
7909            ProcessRecord pr = procsToKill.get(i);
7910            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7911                pr.kill("remove task", true);
7912            } else {
7913                pr.waitingToKill = "remove task";
7914            }
7915        }
7916    }
7917
7918    private void removeTasksByPackageNameLocked(String packageName, int userId) {
7919        // Remove all tasks with activities in the specified package from the list of recent tasks
7920        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
7921            TaskRecord tr = mRecentTasks.get(i);
7922            if (tr.userId != userId) continue;
7923
7924            ComponentName cn = tr.intent.getComponent();
7925            if (cn != null && cn.getPackageName().equals(packageName)) {
7926                // If the package name matches, remove the task.
7927                removeTaskByIdLocked(tr.taskId, true);
7928            }
7929        }
7930    }
7931
7932    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
7933        final IPackageManager pm = AppGlobals.getPackageManager();
7934        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
7935
7936        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
7937            TaskRecord tr = mRecentTasks.get(i);
7938            if (tr.userId != userId) continue;
7939
7940            ComponentName cn = tr.intent.getComponent();
7941            if (cn != null && cn.getPackageName().equals(packageName)) {
7942                // Skip if component still exists in the package.
7943                if (componentsKnownToExist.contains(cn)) continue;
7944
7945                try {
7946                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
7947                    if (info != null) {
7948                        componentsKnownToExist.add(cn);
7949                    } else {
7950                        removeTaskByIdLocked(tr.taskId, false);
7951                    }
7952                } catch (RemoteException e) {
7953                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
7954                }
7955            }
7956        }
7957    }
7958
7959    /**
7960     * Removes the task with the specified task id.
7961     *
7962     * @param taskId Identifier of the task to be removed.
7963     * @param killProcess Kill any process associated with the task if possible.
7964     * @return Returns true if the given task was found and removed.
7965     */
7966    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
7967        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
7968        if (tr != null) {
7969            tr.removeTaskActivitiesLocked();
7970            cleanUpRemovedTaskLocked(tr, killProcess);
7971            if (tr.isPersistable) {
7972                notifyTaskPersisterLocked(null, true);
7973            }
7974            return true;
7975        }
7976        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
7977        return false;
7978    }
7979
7980    @Override
7981    public boolean removeTask(int taskId) {
7982        synchronized (this) {
7983            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7984                    "removeTask()");
7985            long ident = Binder.clearCallingIdentity();
7986            try {
7987                return removeTaskByIdLocked(taskId, true);
7988            } finally {
7989                Binder.restoreCallingIdentity(ident);
7990            }
7991        }
7992    }
7993
7994    /**
7995     * TODO: Add mController hook
7996     */
7997    @Override
7998    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7999        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8000                "moveTaskToFront()");
8001
8002        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8003        synchronized(this) {
8004            moveTaskToFrontLocked(taskId, flags, options);
8005        }
8006    }
8007
8008    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8009        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8010                Binder.getCallingUid(), -1, -1, "Task to front")) {
8011            ActivityOptions.abort(options);
8012            return;
8013        }
8014        final long origId = Binder.clearCallingIdentity();
8015        try {
8016            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8017            if (task == null) {
8018                Slog.d(TAG, "Could not find task for id: "+ taskId);
8019                return;
8020            }
8021            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8022                mStackSupervisor.showLockTaskToast();
8023                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8024                return;
8025            }
8026            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8027            if (prev != null && prev.isRecentsActivity()) {
8028                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8029            }
8030            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8031        } finally {
8032            Binder.restoreCallingIdentity(origId);
8033        }
8034        ActivityOptions.abort(options);
8035    }
8036
8037    /**
8038     * Moves an activity, and all of the other activities within the same task, to the bottom
8039     * of the history stack.  The activity's order within the task is unchanged.
8040     *
8041     * @param token A reference to the activity we wish to move
8042     * @param nonRoot If false then this only works if the activity is the root
8043     *                of a task; if true it will work for any activity in a task.
8044     * @return Returns true if the move completed, false if not.
8045     */
8046    @Override
8047    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8048        enforceNotIsolatedCaller("moveActivityTaskToBack");
8049        synchronized(this) {
8050            final long origId = Binder.clearCallingIdentity();
8051            try {
8052                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8053                if (taskId >= 0) {
8054                    if ((mStackSupervisor.mLockTaskModeTask != null)
8055                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8056                        mStackSupervisor.showLockTaskToast();
8057                        return false;
8058                    }
8059                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8060                }
8061            } finally {
8062                Binder.restoreCallingIdentity(origId);
8063            }
8064        }
8065        return false;
8066    }
8067
8068    @Override
8069    public void moveTaskBackwards(int task) {
8070        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8071                "moveTaskBackwards()");
8072
8073        synchronized(this) {
8074            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8075                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8076                return;
8077            }
8078            final long origId = Binder.clearCallingIdentity();
8079            moveTaskBackwardsLocked(task);
8080            Binder.restoreCallingIdentity(origId);
8081        }
8082    }
8083
8084    private final void moveTaskBackwardsLocked(int task) {
8085        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8086    }
8087
8088    @Override
8089    public IBinder getHomeActivityToken() throws RemoteException {
8090        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8091                "getHomeActivityToken()");
8092        synchronized (this) {
8093            return mStackSupervisor.getHomeActivityToken();
8094        }
8095    }
8096
8097    @Override
8098    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8099            IActivityContainerCallback callback) throws RemoteException {
8100        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8101                "createActivityContainer()");
8102        synchronized (this) {
8103            if (parentActivityToken == null) {
8104                throw new IllegalArgumentException("parent token must not be null");
8105            }
8106            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8107            if (r == null) {
8108                return null;
8109            }
8110            if (callback == null) {
8111                throw new IllegalArgumentException("callback must not be null");
8112            }
8113            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8114        }
8115    }
8116
8117    @Override
8118    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8119        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8120                "deleteActivityContainer()");
8121        synchronized (this) {
8122            mStackSupervisor.deleteActivityContainer(container);
8123        }
8124    }
8125
8126    @Override
8127    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8128        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8129                "createStackOnDisplay()");
8130        synchronized (this) {
8131            final int stackId = mStackSupervisor.getNextStackId();
8132            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8133            if (stack == null) {
8134                return null;
8135            }
8136            return stack.mActivityContainer;
8137        }
8138    }
8139
8140    @Override
8141    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8142            throws RemoteException {
8143        synchronized (this) {
8144            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8145            if (stack != null) {
8146                return stack.mActivityContainer;
8147            }
8148            return null;
8149        }
8150    }
8151
8152    @Override
8153    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8154        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8155                "moveTaskToStack()");
8156        if (stackId == HOME_STACK_ID) {
8157            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8158                    new RuntimeException("here").fillInStackTrace());
8159        }
8160        synchronized (this) {
8161            long ident = Binder.clearCallingIdentity();
8162            try {
8163                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8164                        + stackId + " toTop=" + toTop);
8165                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8166            } finally {
8167                Binder.restoreCallingIdentity(ident);
8168            }
8169        }
8170    }
8171
8172    @Override
8173    public void resizeStack(int stackId, Rect bounds) {
8174        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8175                "resizeStack()");
8176        long ident = Binder.clearCallingIdentity();
8177        try {
8178            synchronized (this) {
8179                mStackSupervisor.resizeStackLocked(stackId, bounds);
8180            }
8181        } finally {
8182            Binder.restoreCallingIdentity(ident);
8183        }
8184    }
8185
8186    @Override
8187    public List<StackInfo> getAllStackInfos() {
8188        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8189                "getAllStackInfos()");
8190        long ident = Binder.clearCallingIdentity();
8191        try {
8192            synchronized (this) {
8193                return mStackSupervisor.getAllStackInfosLocked();
8194            }
8195        } finally {
8196            Binder.restoreCallingIdentity(ident);
8197        }
8198    }
8199
8200    @Override
8201    public StackInfo getStackInfo(int stackId) {
8202        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8203                "getStackInfo()");
8204        long ident = Binder.clearCallingIdentity();
8205        try {
8206            synchronized (this) {
8207                return mStackSupervisor.getStackInfoLocked(stackId);
8208            }
8209        } finally {
8210            Binder.restoreCallingIdentity(ident);
8211        }
8212    }
8213
8214    @Override
8215    public boolean isInHomeStack(int taskId) {
8216        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8217                "getStackInfo()");
8218        long ident = Binder.clearCallingIdentity();
8219        try {
8220            synchronized (this) {
8221                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8222                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8223            }
8224        } finally {
8225            Binder.restoreCallingIdentity(ident);
8226        }
8227    }
8228
8229    @Override
8230    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8231        synchronized(this) {
8232            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8233        }
8234    }
8235
8236    private boolean isLockTaskAuthorized(String pkg) {
8237        final DevicePolicyManager dpm = (DevicePolicyManager)
8238                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8239        try {
8240            int uid = mContext.getPackageManager().getPackageUid(pkg,
8241                    Binder.getCallingUserHandle().getIdentifier());
8242            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8243        } catch (NameNotFoundException e) {
8244            return false;
8245        }
8246    }
8247
8248    void startLockTaskMode(TaskRecord task) {
8249        final String pkg;
8250        synchronized (this) {
8251            pkg = task.intent.getComponent().getPackageName();
8252        }
8253        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8254        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8255            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8256                    StatusBarManagerInternal.class);
8257            if (statusBarManager != null) {
8258                statusBarManager.showScreenPinningRequest();
8259            }
8260            return;
8261        }
8262        long ident = Binder.clearCallingIdentity();
8263        try {
8264            synchronized (this) {
8265                // Since we lost lock on task, make sure it is still there.
8266                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8267                if (task != null) {
8268                    if (!isSystemInitiated
8269                            && ((mStackSupervisor.getFocusedStack() == null)
8270                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8271                        throw new IllegalArgumentException("Invalid task, not in foreground");
8272                    }
8273                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated,
8274                            "startLockTask");
8275                }
8276            }
8277        } finally {
8278            Binder.restoreCallingIdentity(ident);
8279        }
8280    }
8281
8282    @Override
8283    public void startLockTaskMode(int taskId) {
8284        final TaskRecord task;
8285        long ident = Binder.clearCallingIdentity();
8286        try {
8287            synchronized (this) {
8288                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8289            }
8290        } finally {
8291            Binder.restoreCallingIdentity(ident);
8292        }
8293        if (task != null) {
8294            startLockTaskMode(task);
8295        }
8296    }
8297
8298    @Override
8299    public void startLockTaskMode(IBinder token) {
8300        final TaskRecord task;
8301        long ident = Binder.clearCallingIdentity();
8302        try {
8303            synchronized (this) {
8304                final ActivityRecord r = ActivityRecord.forToken(token);
8305                if (r == null) {
8306                    return;
8307                }
8308                task = r.task;
8309            }
8310        } finally {
8311            Binder.restoreCallingIdentity(ident);
8312        }
8313        if (task != null) {
8314            startLockTaskMode(task);
8315        }
8316    }
8317
8318    @Override
8319    public void startLockTaskModeOnCurrent() throws RemoteException {
8320        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8321                "startLockTaskModeOnCurrent");
8322        long ident = Binder.clearCallingIdentity();
8323        try {
8324            ActivityRecord r = null;
8325            synchronized (this) {
8326                r = mStackSupervisor.topRunningActivityLocked();
8327            }
8328            startLockTaskMode(r.task);
8329        } finally {
8330            Binder.restoreCallingIdentity(ident);
8331        }
8332    }
8333
8334    @Override
8335    public void stopLockTaskMode() {
8336        // Verify that the user matches the package of the intent for the TaskRecord
8337        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8338        // and stopLockTaskMode.
8339        final int callingUid = Binder.getCallingUid();
8340        if (callingUid != Process.SYSTEM_UID) {
8341            try {
8342                String pkg =
8343                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8344                int uid = mContext.getPackageManager().getPackageUid(pkg,
8345                        Binder.getCallingUserHandle().getIdentifier());
8346                if (uid != callingUid) {
8347                    throw new SecurityException("Invalid uid, expected " + uid);
8348                }
8349            } catch (NameNotFoundException e) {
8350                Log.d(TAG, "stopLockTaskMode " + e);
8351                return;
8352            }
8353        }
8354        long ident = Binder.clearCallingIdentity();
8355        try {
8356            Log.d(TAG, "stopLockTaskMode");
8357            // Stop lock task
8358            synchronized (this) {
8359                mStackSupervisor.setLockTaskModeLocked(null, false, "stopLockTask");
8360            }
8361        } finally {
8362            Binder.restoreCallingIdentity(ident);
8363        }
8364    }
8365
8366    @Override
8367    public void stopLockTaskModeOnCurrent() throws RemoteException {
8368        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8369                "stopLockTaskModeOnCurrent");
8370        long ident = Binder.clearCallingIdentity();
8371        try {
8372            stopLockTaskMode();
8373        } finally {
8374            Binder.restoreCallingIdentity(ident);
8375        }
8376    }
8377
8378    @Override
8379    public boolean isInLockTaskMode() {
8380        synchronized (this) {
8381            return mStackSupervisor.isInLockTaskMode();
8382        }
8383    }
8384
8385    // =========================================================
8386    // CONTENT PROVIDERS
8387    // =========================================================
8388
8389    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8390        List<ProviderInfo> providers = null;
8391        try {
8392            providers = AppGlobals.getPackageManager().
8393                queryContentProviders(app.processName, app.uid,
8394                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8395        } catch (RemoteException ex) {
8396        }
8397        if (DEBUG_MU)
8398            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8399        int userId = app.userId;
8400        if (providers != null) {
8401            int N = providers.size();
8402            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8403            for (int i=0; i<N; i++) {
8404                ProviderInfo cpi =
8405                    (ProviderInfo)providers.get(i);
8406                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8407                        cpi.name, cpi.flags);
8408                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8409                    // This is a singleton provider, but a user besides the
8410                    // default user is asking to initialize a process it runs
8411                    // in...  well, no, it doesn't actually run in this process,
8412                    // it runs in the process of the default user.  Get rid of it.
8413                    providers.remove(i);
8414                    N--;
8415                    i--;
8416                    continue;
8417                }
8418
8419                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8420                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8421                if (cpr == null) {
8422                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8423                    mProviderMap.putProviderByClass(comp, cpr);
8424                }
8425                if (DEBUG_MU)
8426                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8427                app.pubProviders.put(cpi.name, cpr);
8428                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8429                    // Don't add this if it is a platform component that is marked
8430                    // to run in multiple processes, because this is actually
8431                    // part of the framework so doesn't make sense to track as a
8432                    // separate apk in the process.
8433                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8434                            mProcessStats);
8435                }
8436                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8437            }
8438        }
8439        return providers;
8440    }
8441
8442    /**
8443     * Check if {@link ProcessRecord} has a possible chance at accessing the
8444     * given {@link ProviderInfo}. Final permission checking is always done
8445     * in {@link ContentProvider}.
8446     */
8447    private final String checkContentProviderPermissionLocked(
8448            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8449        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8450        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8451        boolean checkedGrants = false;
8452        if (checkUser) {
8453            // Looking for cross-user grants before enforcing the typical cross-users permissions
8454            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8455            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8456                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8457                    return null;
8458                }
8459                checkedGrants = true;
8460            }
8461            userId = handleIncomingUser(callingPid, callingUid, userId,
8462                    false, ALLOW_NON_FULL,
8463                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8464            if (userId != tmpTargetUserId) {
8465                // When we actually went to determine the final targer user ID, this ended
8466                // up different than our initial check for the authority.  This is because
8467                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8468                // SELF.  So we need to re-check the grants again.
8469                checkedGrants = false;
8470            }
8471        }
8472        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8473                cpi.applicationInfo.uid, cpi.exported)
8474                == PackageManager.PERMISSION_GRANTED) {
8475            return null;
8476        }
8477        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8478                cpi.applicationInfo.uid, cpi.exported)
8479                == PackageManager.PERMISSION_GRANTED) {
8480            return null;
8481        }
8482
8483        PathPermission[] pps = cpi.pathPermissions;
8484        if (pps != null) {
8485            int i = pps.length;
8486            while (i > 0) {
8487                i--;
8488                PathPermission pp = pps[i];
8489                String pprperm = pp.getReadPermission();
8490                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8491                        cpi.applicationInfo.uid, cpi.exported)
8492                        == PackageManager.PERMISSION_GRANTED) {
8493                    return null;
8494                }
8495                String ppwperm = pp.getWritePermission();
8496                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8497                        cpi.applicationInfo.uid, cpi.exported)
8498                        == PackageManager.PERMISSION_GRANTED) {
8499                    return null;
8500                }
8501            }
8502        }
8503        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8504            return null;
8505        }
8506
8507        String msg;
8508        if (!cpi.exported) {
8509            msg = "Permission Denial: opening provider " + cpi.name
8510                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8511                    + ", uid=" + callingUid + ") that is not exported from uid "
8512                    + cpi.applicationInfo.uid;
8513        } else {
8514            msg = "Permission Denial: opening provider " + cpi.name
8515                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8516                    + ", uid=" + callingUid + ") requires "
8517                    + cpi.readPermission + " or " + cpi.writePermission;
8518        }
8519        Slog.w(TAG, msg);
8520        return msg;
8521    }
8522
8523    /**
8524     * Returns if the ContentProvider has granted a uri to callingUid
8525     */
8526    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8527        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8528        if (perms != null) {
8529            for (int i=perms.size()-1; i>=0; i--) {
8530                GrantUri grantUri = perms.keyAt(i);
8531                if (grantUri.sourceUserId == userId || !checkUser) {
8532                    if (matchesProvider(grantUri.uri, cpi)) {
8533                        return true;
8534                    }
8535                }
8536            }
8537        }
8538        return false;
8539    }
8540
8541    /**
8542     * Returns true if the uri authority is one of the authorities specified in the provider.
8543     */
8544    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8545        String uriAuth = uri.getAuthority();
8546        String cpiAuth = cpi.authority;
8547        if (cpiAuth.indexOf(';') == -1) {
8548            return cpiAuth.equals(uriAuth);
8549        }
8550        String[] cpiAuths = cpiAuth.split(";");
8551        int length = cpiAuths.length;
8552        for (int i = 0; i < length; i++) {
8553            if (cpiAuths[i].equals(uriAuth)) return true;
8554        }
8555        return false;
8556    }
8557
8558    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8559            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8560        if (r != null) {
8561            for (int i=0; i<r.conProviders.size(); i++) {
8562                ContentProviderConnection conn = r.conProviders.get(i);
8563                if (conn.provider == cpr) {
8564                    if (DEBUG_PROVIDER) Slog.v(TAG,
8565                            "Adding provider requested by "
8566                            + r.processName + " from process "
8567                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8568                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8569                    if (stable) {
8570                        conn.stableCount++;
8571                        conn.numStableIncs++;
8572                    } else {
8573                        conn.unstableCount++;
8574                        conn.numUnstableIncs++;
8575                    }
8576                    return conn;
8577                }
8578            }
8579            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8580            if (stable) {
8581                conn.stableCount = 1;
8582                conn.numStableIncs = 1;
8583            } else {
8584                conn.unstableCount = 1;
8585                conn.numUnstableIncs = 1;
8586            }
8587            cpr.connections.add(conn);
8588            r.conProviders.add(conn);
8589            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
8590            return conn;
8591        }
8592        cpr.addExternalProcessHandleLocked(externalProcessToken);
8593        return null;
8594    }
8595
8596    boolean decProviderCountLocked(ContentProviderConnection conn,
8597            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8598        if (conn != null) {
8599            cpr = conn.provider;
8600            if (DEBUG_PROVIDER) Slog.v(TAG,
8601                    "Removing provider requested by "
8602                    + conn.client.processName + " from process "
8603                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8604                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8605            if (stable) {
8606                conn.stableCount--;
8607            } else {
8608                conn.unstableCount--;
8609            }
8610            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8611                cpr.connections.remove(conn);
8612                conn.client.conProviders.remove(conn);
8613                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
8614                return true;
8615            }
8616            return false;
8617        }
8618        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8619        return false;
8620    }
8621
8622    private void checkTime(long startTime, String where) {
8623        long now = SystemClock.elapsedRealtime();
8624        if ((now-startTime) > 1000) {
8625            // If we are taking more than a second, log about it.
8626            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
8627        }
8628    }
8629
8630    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8631            String name, IBinder token, boolean stable, int userId) {
8632        ContentProviderRecord cpr;
8633        ContentProviderConnection conn = null;
8634        ProviderInfo cpi = null;
8635
8636        synchronized(this) {
8637            long startTime = SystemClock.elapsedRealtime();
8638
8639            ProcessRecord r = null;
8640            if (caller != null) {
8641                r = getRecordForAppLocked(caller);
8642                if (r == null) {
8643                    throw new SecurityException(
8644                            "Unable to find app for caller " + caller
8645                          + " (pid=" + Binder.getCallingPid()
8646                          + ") when getting content provider " + name);
8647                }
8648            }
8649
8650            boolean checkCrossUser = true;
8651
8652            checkTime(startTime, "getContentProviderImpl: getProviderByName");
8653
8654            // First check if this content provider has been published...
8655            cpr = mProviderMap.getProviderByName(name, userId);
8656            // If that didn't work, check if it exists for user 0 and then
8657            // verify that it's a singleton provider before using it.
8658            if (cpr == null && userId != UserHandle.USER_OWNER) {
8659                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8660                if (cpr != null) {
8661                    cpi = cpr.info;
8662                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8663                            cpi.name, cpi.flags)
8664                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8665                        userId = UserHandle.USER_OWNER;
8666                        checkCrossUser = false;
8667                    } else {
8668                        cpr = null;
8669                        cpi = null;
8670                    }
8671                }
8672            }
8673
8674            boolean providerRunning = cpr != null;
8675            if (providerRunning) {
8676                cpi = cpr.info;
8677                String msg;
8678                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
8679                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8680                        != null) {
8681                    throw new SecurityException(msg);
8682                }
8683                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
8684
8685                if (r != null && cpr.canRunHere(r)) {
8686                    // This provider has been published or is in the process
8687                    // of being published...  but it is also allowed to run
8688                    // in the caller's process, so don't make a connection
8689                    // and just let the caller instantiate its own instance.
8690                    ContentProviderHolder holder = cpr.newHolder(null);
8691                    // don't give caller the provider object, it needs
8692                    // to make its own.
8693                    holder.provider = null;
8694                    return holder;
8695                }
8696
8697                final long origId = Binder.clearCallingIdentity();
8698
8699                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
8700
8701                // In this case the provider instance already exists, so we can
8702                // return it right away.
8703                conn = incProviderCountLocked(r, cpr, token, stable);
8704                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8705                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8706                        // If this is a perceptible app accessing the provider,
8707                        // make sure to count it as being accessed and thus
8708                        // back up on the LRU list.  This is good because
8709                        // content providers are often expensive to start.
8710                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
8711                        updateLruProcessLocked(cpr.proc, false, null);
8712                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
8713                    }
8714                }
8715
8716                if (cpr.proc != null) {
8717                    if (false) {
8718                        if (cpr.name.flattenToShortString().equals(
8719                                "com.android.providers.calendar/.CalendarProvider2")) {
8720                            Slog.v(TAG, "****************** KILLING "
8721                                + cpr.name.flattenToShortString());
8722                            Process.killProcess(cpr.proc.pid);
8723                        }
8724                    }
8725                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
8726                    boolean success = updateOomAdjLocked(cpr.proc);
8727                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
8728                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8729                    // NOTE: there is still a race here where a signal could be
8730                    // pending on the process even though we managed to update its
8731                    // adj level.  Not sure what to do about this, but at least
8732                    // the race is now smaller.
8733                    if (!success) {
8734                        // Uh oh...  it looks like the provider's process
8735                        // has been killed on us.  We need to wait for a new
8736                        // process to be started, and make sure its death
8737                        // doesn't kill our process.
8738                        Slog.i(TAG,
8739                                "Existing provider " + cpr.name.flattenToShortString()
8740                                + " is crashing; detaching " + r);
8741                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8742                        checkTime(startTime, "getContentProviderImpl: before appDied");
8743                        appDiedLocked(cpr.proc);
8744                        checkTime(startTime, "getContentProviderImpl: after appDied");
8745                        if (!lastRef) {
8746                            // This wasn't the last ref our process had on
8747                            // the provider...  we have now been killed, bail.
8748                            return null;
8749                        }
8750                        providerRunning = false;
8751                        conn = null;
8752                    }
8753                }
8754
8755                Binder.restoreCallingIdentity(origId);
8756            }
8757
8758            boolean singleton;
8759            if (!providerRunning) {
8760                try {
8761                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
8762                    cpi = AppGlobals.getPackageManager().
8763                        resolveContentProvider(name,
8764                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8765                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
8766                } catch (RemoteException ex) {
8767                }
8768                if (cpi == null) {
8769                    return null;
8770                }
8771                // If the provider is a singleton AND
8772                // (it's a call within the same user || the provider is a
8773                // privileged app)
8774                // Then allow connecting to the singleton provider
8775                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8776                        cpi.name, cpi.flags)
8777                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8778                if (singleton) {
8779                    userId = UserHandle.USER_OWNER;
8780                }
8781                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8782                checkTime(startTime, "getContentProviderImpl: got app info for user");
8783
8784                String msg;
8785                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
8786                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8787                        != null) {
8788                    throw new SecurityException(msg);
8789                }
8790                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
8791
8792                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8793                        && !cpi.processName.equals("system")) {
8794                    // If this content provider does not run in the system
8795                    // process, and the system is not yet ready to run other
8796                    // processes, then fail fast instead of hanging.
8797                    throw new IllegalArgumentException(
8798                            "Attempt to launch content provider before system ready");
8799                }
8800
8801                // Make sure that the user who owns this provider is running.  If not,
8802                // we don't want to allow it to run.
8803                if (!isUserRunningLocked(userId, false)) {
8804                    Slog.w(TAG, "Unable to launch app "
8805                            + cpi.applicationInfo.packageName + "/"
8806                            + cpi.applicationInfo.uid + " for provider "
8807                            + name + ": user " + userId + " is stopped");
8808                    return null;
8809                }
8810
8811                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8812                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
8813                cpr = mProviderMap.getProviderByClass(comp, userId);
8814                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
8815                final boolean firstClass = cpr == null;
8816                if (firstClass) {
8817                    final long ident = Binder.clearCallingIdentity();
8818                    try {
8819                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
8820                        ApplicationInfo ai =
8821                            AppGlobals.getPackageManager().
8822                                getApplicationInfo(
8823                                        cpi.applicationInfo.packageName,
8824                                        STOCK_PM_FLAGS, userId);
8825                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
8826                        if (ai == null) {
8827                            Slog.w(TAG, "No package info for content provider "
8828                                    + cpi.name);
8829                            return null;
8830                        }
8831                        ai = getAppInfoForUser(ai, userId);
8832                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8833                    } catch (RemoteException ex) {
8834                        // pm is in same process, this will never happen.
8835                    } finally {
8836                        Binder.restoreCallingIdentity(ident);
8837                    }
8838                }
8839
8840                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
8841
8842                if (r != null && cpr.canRunHere(r)) {
8843                    // If this is a multiprocess provider, then just return its
8844                    // info and allow the caller to instantiate it.  Only do
8845                    // this if the provider is the same user as the caller's
8846                    // process, or can run as root (so can be in any process).
8847                    return cpr.newHolder(null);
8848                }
8849
8850                if (DEBUG_PROVIDER) {
8851                    RuntimeException e = new RuntimeException("here");
8852                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8853                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8854                }
8855
8856                // This is single process, and our app is now connecting to it.
8857                // See if we are already in the process of launching this
8858                // provider.
8859                final int N = mLaunchingProviders.size();
8860                int i;
8861                for (i=0; i<N; i++) {
8862                    if (mLaunchingProviders.get(i) == cpr) {
8863                        break;
8864                    }
8865                }
8866
8867                // If the provider is not already being launched, then get it
8868                // started.
8869                if (i >= N) {
8870                    final long origId = Binder.clearCallingIdentity();
8871
8872                    try {
8873                        // Content provider is now in use, its package can't be stopped.
8874                        try {
8875                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
8876                            AppGlobals.getPackageManager().setPackageStoppedState(
8877                                    cpr.appInfo.packageName, false, userId);
8878                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
8879                        } catch (RemoteException e) {
8880                        } catch (IllegalArgumentException e) {
8881                            Slog.w(TAG, "Failed trying to unstop package "
8882                                    + cpr.appInfo.packageName + ": " + e);
8883                        }
8884
8885                        // Use existing process if already started
8886                        checkTime(startTime, "getContentProviderImpl: looking for process record");
8887                        ProcessRecord proc = getProcessRecordLocked(
8888                                cpi.processName, cpr.appInfo.uid, false);
8889                        if (proc != null && proc.thread != null) {
8890                            if (DEBUG_PROVIDER) {
8891                                Slog.d(TAG, "Installing in existing process " + proc);
8892                            }
8893                            if (!proc.pubProviders.containsKey(cpi.name)) {
8894                                checkTime(startTime, "getContentProviderImpl: scheduling install");
8895                                proc.pubProviders.put(cpi.name, cpr);
8896                                try {
8897                                    proc.thread.scheduleInstallProvider(cpi);
8898                                } catch (RemoteException e) {
8899                                }
8900                            }
8901                        } else {
8902                            checkTime(startTime, "getContentProviderImpl: before start process");
8903                            proc = startProcessLocked(cpi.processName,
8904                                    cpr.appInfo, false, 0, "content provider",
8905                                    new ComponentName(cpi.applicationInfo.packageName,
8906                                            cpi.name), false, false, false);
8907                            checkTime(startTime, "getContentProviderImpl: after start process");
8908                            if (proc == null) {
8909                                Slog.w(TAG, "Unable to launch app "
8910                                        + cpi.applicationInfo.packageName + "/"
8911                                        + cpi.applicationInfo.uid + " for provider "
8912                                        + name + ": process is bad");
8913                                return null;
8914                            }
8915                        }
8916                        cpr.launchingApp = proc;
8917                        mLaunchingProviders.add(cpr);
8918                    } finally {
8919                        Binder.restoreCallingIdentity(origId);
8920                    }
8921                }
8922
8923                checkTime(startTime, "getContentProviderImpl: updating data structures");
8924
8925                // Make sure the provider is published (the same provider class
8926                // may be published under multiple names).
8927                if (firstClass) {
8928                    mProviderMap.putProviderByClass(comp, cpr);
8929                }
8930
8931                mProviderMap.putProviderByName(name, cpr);
8932                conn = incProviderCountLocked(r, cpr, token, stable);
8933                if (conn != null) {
8934                    conn.waiting = true;
8935                }
8936            }
8937            checkTime(startTime, "getContentProviderImpl: done!");
8938        }
8939
8940        // Wait for the provider to be published...
8941        synchronized (cpr) {
8942            while (cpr.provider == null) {
8943                if (cpr.launchingApp == null) {
8944                    Slog.w(TAG, "Unable to launch app "
8945                            + cpi.applicationInfo.packageName + "/"
8946                            + cpi.applicationInfo.uid + " for provider "
8947                            + name + ": launching app became null");
8948                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8949                            UserHandle.getUserId(cpi.applicationInfo.uid),
8950                            cpi.applicationInfo.packageName,
8951                            cpi.applicationInfo.uid, name);
8952                    return null;
8953                }
8954                try {
8955                    if (DEBUG_MU) {
8956                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8957                                + cpr.launchingApp);
8958                    }
8959                    if (conn != null) {
8960                        conn.waiting = true;
8961                    }
8962                    cpr.wait();
8963                } catch (InterruptedException ex) {
8964                } finally {
8965                    if (conn != null) {
8966                        conn.waiting = false;
8967                    }
8968                }
8969            }
8970        }
8971        return cpr != null ? cpr.newHolder(conn) : null;
8972    }
8973
8974    @Override
8975    public final ContentProviderHolder getContentProvider(
8976            IApplicationThread caller, String name, int userId, boolean stable) {
8977        enforceNotIsolatedCaller("getContentProvider");
8978        if (caller == null) {
8979            String msg = "null IApplicationThread when getting content provider "
8980                    + name;
8981            Slog.w(TAG, msg);
8982            throw new SecurityException(msg);
8983        }
8984        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8985        // with cross-user grant.
8986        return getContentProviderImpl(caller, name, null, stable, userId);
8987    }
8988
8989    public ContentProviderHolder getContentProviderExternal(
8990            String name, int userId, IBinder token) {
8991        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8992            "Do not have permission in call getContentProviderExternal()");
8993        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8994                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8995        return getContentProviderExternalUnchecked(name, token, userId);
8996    }
8997
8998    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8999            IBinder token, int userId) {
9000        return getContentProviderImpl(null, name, token, true, userId);
9001    }
9002
9003    /**
9004     * Drop a content provider from a ProcessRecord's bookkeeping
9005     */
9006    public void removeContentProvider(IBinder connection, boolean stable) {
9007        enforceNotIsolatedCaller("removeContentProvider");
9008        long ident = Binder.clearCallingIdentity();
9009        try {
9010            synchronized (this) {
9011                ContentProviderConnection conn;
9012                try {
9013                    conn = (ContentProviderConnection)connection;
9014                } catch (ClassCastException e) {
9015                    String msg ="removeContentProvider: " + connection
9016                            + " not a ContentProviderConnection";
9017                    Slog.w(TAG, msg);
9018                    throw new IllegalArgumentException(msg);
9019                }
9020                if (conn == null) {
9021                    throw new NullPointerException("connection is null");
9022                }
9023                if (decProviderCountLocked(conn, null, null, stable)) {
9024                    updateOomAdjLocked();
9025                }
9026            }
9027        } finally {
9028            Binder.restoreCallingIdentity(ident);
9029        }
9030    }
9031
9032    public void removeContentProviderExternal(String name, IBinder token) {
9033        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9034            "Do not have permission in call removeContentProviderExternal()");
9035        int userId = UserHandle.getCallingUserId();
9036        long ident = Binder.clearCallingIdentity();
9037        try {
9038            removeContentProviderExternalUnchecked(name, token, userId);
9039        } finally {
9040            Binder.restoreCallingIdentity(ident);
9041        }
9042    }
9043
9044    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9045        synchronized (this) {
9046            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9047            if(cpr == null) {
9048                //remove from mProvidersByClass
9049                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9050                return;
9051            }
9052
9053            //update content provider record entry info
9054            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9055            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9056            if (localCpr.hasExternalProcessHandles()) {
9057                if (localCpr.removeExternalProcessHandleLocked(token)) {
9058                    updateOomAdjLocked();
9059                } else {
9060                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9061                            + " with no external reference for token: "
9062                            + token + ".");
9063                }
9064            } else {
9065                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9066                        + " with no external references.");
9067            }
9068        }
9069    }
9070
9071    public final void publishContentProviders(IApplicationThread caller,
9072            List<ContentProviderHolder> providers) {
9073        if (providers == null) {
9074            return;
9075        }
9076
9077        enforceNotIsolatedCaller("publishContentProviders");
9078        synchronized (this) {
9079            final ProcessRecord r = getRecordForAppLocked(caller);
9080            if (DEBUG_MU)
9081                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9082            if (r == null) {
9083                throw new SecurityException(
9084                        "Unable to find app for caller " + caller
9085                      + " (pid=" + Binder.getCallingPid()
9086                      + ") when publishing content providers");
9087            }
9088
9089            final long origId = Binder.clearCallingIdentity();
9090
9091            final int N = providers.size();
9092            for (int i=0; i<N; i++) {
9093                ContentProviderHolder src = providers.get(i);
9094                if (src == null || src.info == null || src.provider == null) {
9095                    continue;
9096                }
9097                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9098                if (DEBUG_MU)
9099                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9100                if (dst != null) {
9101                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9102                    mProviderMap.putProviderByClass(comp, dst);
9103                    String names[] = dst.info.authority.split(";");
9104                    for (int j = 0; j < names.length; j++) {
9105                        mProviderMap.putProviderByName(names[j], dst);
9106                    }
9107
9108                    int NL = mLaunchingProviders.size();
9109                    int j;
9110                    for (j=0; j<NL; j++) {
9111                        if (mLaunchingProviders.get(j) == dst) {
9112                            mLaunchingProviders.remove(j);
9113                            j--;
9114                            NL--;
9115                        }
9116                    }
9117                    synchronized (dst) {
9118                        dst.provider = src.provider;
9119                        dst.proc = r;
9120                        dst.notifyAll();
9121                    }
9122                    updateOomAdjLocked(r);
9123                }
9124            }
9125
9126            Binder.restoreCallingIdentity(origId);
9127        }
9128    }
9129
9130    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9131        ContentProviderConnection conn;
9132        try {
9133            conn = (ContentProviderConnection)connection;
9134        } catch (ClassCastException e) {
9135            String msg ="refContentProvider: " + connection
9136                    + " not a ContentProviderConnection";
9137            Slog.w(TAG, msg);
9138            throw new IllegalArgumentException(msg);
9139        }
9140        if (conn == null) {
9141            throw new NullPointerException("connection is null");
9142        }
9143
9144        synchronized (this) {
9145            if (stable > 0) {
9146                conn.numStableIncs += stable;
9147            }
9148            stable = conn.stableCount + stable;
9149            if (stable < 0) {
9150                throw new IllegalStateException("stableCount < 0: " + stable);
9151            }
9152
9153            if (unstable > 0) {
9154                conn.numUnstableIncs += unstable;
9155            }
9156            unstable = conn.unstableCount + unstable;
9157            if (unstable < 0) {
9158                throw new IllegalStateException("unstableCount < 0: " + unstable);
9159            }
9160
9161            if ((stable+unstable) <= 0) {
9162                throw new IllegalStateException("ref counts can't go to zero here: stable="
9163                        + stable + " unstable=" + unstable);
9164            }
9165            conn.stableCount = stable;
9166            conn.unstableCount = unstable;
9167            return !conn.dead;
9168        }
9169    }
9170
9171    public void unstableProviderDied(IBinder connection) {
9172        ContentProviderConnection conn;
9173        try {
9174            conn = (ContentProviderConnection)connection;
9175        } catch (ClassCastException e) {
9176            String msg ="refContentProvider: " + connection
9177                    + " not a ContentProviderConnection";
9178            Slog.w(TAG, msg);
9179            throw new IllegalArgumentException(msg);
9180        }
9181        if (conn == null) {
9182            throw new NullPointerException("connection is null");
9183        }
9184
9185        // Safely retrieve the content provider associated with the connection.
9186        IContentProvider provider;
9187        synchronized (this) {
9188            provider = conn.provider.provider;
9189        }
9190
9191        if (provider == null) {
9192            // Um, yeah, we're way ahead of you.
9193            return;
9194        }
9195
9196        // Make sure the caller is being honest with us.
9197        if (provider.asBinder().pingBinder()) {
9198            // Er, no, still looks good to us.
9199            synchronized (this) {
9200                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9201                        + " says " + conn + " died, but we don't agree");
9202                return;
9203            }
9204        }
9205
9206        // Well look at that!  It's dead!
9207        synchronized (this) {
9208            if (conn.provider.provider != provider) {
9209                // But something changed...  good enough.
9210                return;
9211            }
9212
9213            ProcessRecord proc = conn.provider.proc;
9214            if (proc == null || proc.thread == null) {
9215                // Seems like the process is already cleaned up.
9216                return;
9217            }
9218
9219            // As far as we're concerned, this is just like receiving a
9220            // death notification...  just a bit prematurely.
9221            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9222                    + ") early provider death");
9223            final long ident = Binder.clearCallingIdentity();
9224            try {
9225                appDiedLocked(proc);
9226            } finally {
9227                Binder.restoreCallingIdentity(ident);
9228            }
9229        }
9230    }
9231
9232    @Override
9233    public void appNotRespondingViaProvider(IBinder connection) {
9234        enforceCallingPermission(
9235                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9236
9237        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9238        if (conn == null) {
9239            Slog.w(TAG, "ContentProviderConnection is null");
9240            return;
9241        }
9242
9243        final ProcessRecord host = conn.provider.proc;
9244        if (host == null) {
9245            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9246            return;
9247        }
9248
9249        final long token = Binder.clearCallingIdentity();
9250        try {
9251            appNotResponding(host, null, null, false, "ContentProvider not responding");
9252        } finally {
9253            Binder.restoreCallingIdentity(token);
9254        }
9255    }
9256
9257    public final void installSystemProviders() {
9258        List<ProviderInfo> providers;
9259        synchronized (this) {
9260            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9261            providers = generateApplicationProvidersLocked(app);
9262            if (providers != null) {
9263                for (int i=providers.size()-1; i>=0; i--) {
9264                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9265                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9266                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9267                                + ": not system .apk");
9268                        providers.remove(i);
9269                    }
9270                }
9271            }
9272        }
9273        if (providers != null) {
9274            mSystemThread.installSystemProviders(providers);
9275        }
9276
9277        mCoreSettingsObserver = new CoreSettingsObserver(this);
9278
9279        //mUsageStatsService.monitorPackages();
9280    }
9281
9282    /**
9283     * Allows apps to retrieve the MIME type of a URI.
9284     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9285     * users, then it does not need permission to access the ContentProvider.
9286     * Either, it needs cross-user uri grants.
9287     *
9288     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9289     *
9290     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9291     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9292     */
9293    public String getProviderMimeType(Uri uri, int userId) {
9294        enforceNotIsolatedCaller("getProviderMimeType");
9295        final String name = uri.getAuthority();
9296        int callingUid = Binder.getCallingUid();
9297        int callingPid = Binder.getCallingPid();
9298        long ident = 0;
9299        boolean clearedIdentity = false;
9300        userId = unsafeConvertIncomingUser(userId);
9301        if (canClearIdentity(callingPid, callingUid, userId)) {
9302            clearedIdentity = true;
9303            ident = Binder.clearCallingIdentity();
9304        }
9305        ContentProviderHolder holder = null;
9306        try {
9307            holder = getContentProviderExternalUnchecked(name, null, userId);
9308            if (holder != null) {
9309                return holder.provider.getType(uri);
9310            }
9311        } catch (RemoteException e) {
9312            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9313            return null;
9314        } finally {
9315            // We need to clear the identity to call removeContentProviderExternalUnchecked
9316            if (!clearedIdentity) {
9317                ident = Binder.clearCallingIdentity();
9318            }
9319            try {
9320                if (holder != null) {
9321                    removeContentProviderExternalUnchecked(name, null, userId);
9322                }
9323            } finally {
9324                Binder.restoreCallingIdentity(ident);
9325            }
9326        }
9327
9328        return null;
9329    }
9330
9331    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9332        if (UserHandle.getUserId(callingUid) == userId) {
9333            return true;
9334        }
9335        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9336                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9337                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9338                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9339                return true;
9340        }
9341        return false;
9342    }
9343
9344    // =========================================================
9345    // GLOBAL MANAGEMENT
9346    // =========================================================
9347
9348    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9349            boolean isolated, int isolatedUid) {
9350        String proc = customProcess != null ? customProcess : info.processName;
9351        BatteryStatsImpl.Uid.Proc ps = null;
9352        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9353        int uid = info.uid;
9354        if (isolated) {
9355            if (isolatedUid == 0) {
9356                int userId = UserHandle.getUserId(uid);
9357                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9358                while (true) {
9359                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9360                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9361                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9362                    }
9363                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9364                    mNextIsolatedProcessUid++;
9365                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9366                        // No process for this uid, use it.
9367                        break;
9368                    }
9369                    stepsLeft--;
9370                    if (stepsLeft <= 0) {
9371                        return null;
9372                    }
9373                }
9374            } else {
9375                // Special case for startIsolatedProcess (internal only), where
9376                // the uid of the isolated process is specified by the caller.
9377                uid = isolatedUid;
9378            }
9379        }
9380        return new ProcessRecord(stats, info, proc, uid);
9381    }
9382
9383    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9384            String abiOverride) {
9385        ProcessRecord app;
9386        if (!isolated) {
9387            app = getProcessRecordLocked(info.processName, info.uid, true);
9388        } else {
9389            app = null;
9390        }
9391
9392        if (app == null) {
9393            app = newProcessRecordLocked(info, null, isolated, 0);
9394            mProcessNames.put(info.processName, app.uid, app);
9395            if (isolated) {
9396                mIsolatedProcesses.put(app.uid, app);
9397            }
9398            updateLruProcessLocked(app, false, null);
9399            updateOomAdjLocked();
9400        }
9401
9402        // This package really, really can not be stopped.
9403        try {
9404            AppGlobals.getPackageManager().setPackageStoppedState(
9405                    info.packageName, false, UserHandle.getUserId(app.uid));
9406        } catch (RemoteException e) {
9407        } catch (IllegalArgumentException e) {
9408            Slog.w(TAG, "Failed trying to unstop package "
9409                    + info.packageName + ": " + e);
9410        }
9411
9412        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9413                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9414            app.persistent = true;
9415            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9416        }
9417        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9418            mPersistentStartingProcesses.add(app);
9419            startProcessLocked(app, "added application", app.processName, abiOverride,
9420                    null /* entryPoint */, null /* entryPointArgs */);
9421        }
9422
9423        return app;
9424    }
9425
9426    public void unhandledBack() {
9427        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9428                "unhandledBack()");
9429
9430        synchronized(this) {
9431            final long origId = Binder.clearCallingIdentity();
9432            try {
9433                getFocusedStack().unhandledBackLocked();
9434            } finally {
9435                Binder.restoreCallingIdentity(origId);
9436            }
9437        }
9438    }
9439
9440    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9441        enforceNotIsolatedCaller("openContentUri");
9442        final int userId = UserHandle.getCallingUserId();
9443        String name = uri.getAuthority();
9444        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9445        ParcelFileDescriptor pfd = null;
9446        if (cph != null) {
9447            // We record the binder invoker's uid in thread-local storage before
9448            // going to the content provider to open the file.  Later, in the code
9449            // that handles all permissions checks, we look for this uid and use
9450            // that rather than the Activity Manager's own uid.  The effect is that
9451            // we do the check against the caller's permissions even though it looks
9452            // to the content provider like the Activity Manager itself is making
9453            // the request.
9454            Binder token = new Binder();
9455            sCallerIdentity.set(new Identity(
9456                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9457            try {
9458                pfd = cph.provider.openFile(null, uri, "r", null, token);
9459            } catch (FileNotFoundException e) {
9460                // do nothing; pfd will be returned null
9461            } finally {
9462                // Ensure that whatever happens, we clean up the identity state
9463                sCallerIdentity.remove();
9464                // Ensure we're done with the provider.
9465                removeContentProviderExternalUnchecked(name, null, userId);
9466            }
9467        } else {
9468            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9469        }
9470        return pfd;
9471    }
9472
9473    // Actually is sleeping or shutting down or whatever else in the future
9474    // is an inactive state.
9475    public boolean isSleepingOrShuttingDown() {
9476        return isSleeping() || mShuttingDown;
9477    }
9478
9479    public boolean isSleeping() {
9480        return mSleeping;
9481    }
9482
9483    void onWakefulnessChanged(int wakefulness) {
9484        synchronized(this) {
9485            mWakefulness = wakefulness;
9486            updateSleepIfNeededLocked();
9487        }
9488    }
9489
9490    void finishRunningVoiceLocked() {
9491        if (mRunningVoice) {
9492            mRunningVoice = false;
9493            updateSleepIfNeededLocked();
9494        }
9495    }
9496
9497    void updateSleepIfNeededLocked() {
9498        if (mSleeping && !shouldSleepLocked()) {
9499            mSleeping = false;
9500            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9501        } else if (!mSleeping && shouldSleepLocked()) {
9502            mSleeping = true;
9503            mStackSupervisor.goingToSleepLocked();
9504
9505            // Initialize the wake times of all processes.
9506            checkExcessivePowerUsageLocked(false);
9507            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9508            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9509            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9510        }
9511    }
9512
9513    private boolean shouldSleepLocked() {
9514        // Resume applications while running a voice interactor.
9515        if (mRunningVoice) {
9516            return false;
9517        }
9518
9519        switch (mWakefulness) {
9520            case PowerManagerInternal.WAKEFULNESS_AWAKE:
9521            case PowerManagerInternal.WAKEFULNESS_DREAMING:
9522                // If we're interactive but applications are already paused then defer
9523                // resuming them until the lock screen is hidden.
9524                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
9525            case PowerManagerInternal.WAKEFULNESS_DOZING:
9526                // If we're dozing then pause applications whenever the lock screen is shown.
9527                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
9528            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
9529            default:
9530                // If we're asleep then pause applications unconditionally.
9531                return true;
9532        }
9533    }
9534
9535    /** Pokes the task persister. */
9536    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9537        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9538            // Never persist the home stack.
9539            return;
9540        }
9541        mTaskPersister.wakeup(task, flush);
9542    }
9543
9544    /** Notifies all listeners when the task stack has changed. */
9545    void notifyTaskStackChangedLocked() {
9546        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
9547        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
9548        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
9549    }
9550
9551    @Override
9552    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
9553        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
9554    }
9555
9556    @Override
9557    public boolean shutdown(int timeout) {
9558        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9559                != PackageManager.PERMISSION_GRANTED) {
9560            throw new SecurityException("Requires permission "
9561                    + android.Manifest.permission.SHUTDOWN);
9562        }
9563
9564        boolean timedout = false;
9565
9566        synchronized(this) {
9567            mShuttingDown = true;
9568            updateEventDispatchingLocked();
9569            timedout = mStackSupervisor.shutdownLocked(timeout);
9570        }
9571
9572        mAppOpsService.shutdown();
9573        if (mUsageStatsService != null) {
9574            mUsageStatsService.prepareShutdown();
9575        }
9576        mBatteryStatsService.shutdown();
9577        synchronized (this) {
9578            mProcessStats.shutdownLocked();
9579            notifyTaskPersisterLocked(null, true);
9580        }
9581
9582        return timedout;
9583    }
9584
9585    public final void activitySlept(IBinder token) {
9586        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9587
9588        final long origId = Binder.clearCallingIdentity();
9589
9590        synchronized (this) {
9591            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9592            if (r != null) {
9593                mStackSupervisor.activitySleptLocked(r);
9594            }
9595        }
9596
9597        Binder.restoreCallingIdentity(origId);
9598    }
9599
9600    private String lockScreenShownToString() {
9601        switch (mLockScreenShown) {
9602            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
9603            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
9604            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
9605            default: return "Unknown=" + mLockScreenShown;
9606        }
9607    }
9608
9609    void logLockScreen(String msg) {
9610        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
9611                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
9612                + PowerManagerInternal.wakefulnessToString(mWakefulness)
9613                + " mSleeping=" + mSleeping);
9614    }
9615
9616    void startRunningVoiceLocked() {
9617        if (!mRunningVoice) {
9618            mRunningVoice = true;
9619            updateSleepIfNeededLocked();
9620        }
9621    }
9622
9623    private void updateEventDispatchingLocked() {
9624        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
9625    }
9626
9627    public void setLockScreenShown(boolean shown) {
9628        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9629                != PackageManager.PERMISSION_GRANTED) {
9630            throw new SecurityException("Requires permission "
9631                    + android.Manifest.permission.DEVICE_POWER);
9632        }
9633
9634        synchronized(this) {
9635            long ident = Binder.clearCallingIdentity();
9636            try {
9637                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9638                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
9639                updateSleepIfNeededLocked();
9640            } finally {
9641                Binder.restoreCallingIdentity(ident);
9642            }
9643        }
9644    }
9645
9646    @Override
9647    public void stopAppSwitches() {
9648        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9649                != PackageManager.PERMISSION_GRANTED) {
9650            throw new SecurityException("Requires permission "
9651                    + android.Manifest.permission.STOP_APP_SWITCHES);
9652        }
9653
9654        synchronized(this) {
9655            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9656                    + APP_SWITCH_DELAY_TIME;
9657            mDidAppSwitch = false;
9658            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9659            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9660            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9661        }
9662    }
9663
9664    public void resumeAppSwitches() {
9665        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9666                != PackageManager.PERMISSION_GRANTED) {
9667            throw new SecurityException("Requires permission "
9668                    + android.Manifest.permission.STOP_APP_SWITCHES);
9669        }
9670
9671        synchronized(this) {
9672            // Note that we don't execute any pending app switches... we will
9673            // let those wait until either the timeout, or the next start
9674            // activity request.
9675            mAppSwitchesAllowedTime = 0;
9676        }
9677    }
9678
9679    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
9680            int callingPid, int callingUid, String name) {
9681        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9682            return true;
9683        }
9684
9685        int perm = checkComponentPermission(
9686                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
9687                sourceUid, -1, true);
9688        if (perm == PackageManager.PERMISSION_GRANTED) {
9689            return true;
9690        }
9691
9692        // If the actual IPC caller is different from the logical source, then
9693        // also see if they are allowed to control app switches.
9694        if (callingUid != -1 && callingUid != sourceUid) {
9695            perm = checkComponentPermission(
9696                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9697                    callingUid, -1, true);
9698            if (perm == PackageManager.PERMISSION_GRANTED) {
9699                return true;
9700            }
9701        }
9702
9703        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
9704        return false;
9705    }
9706
9707    public void setDebugApp(String packageName, boolean waitForDebugger,
9708            boolean persistent) {
9709        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9710                "setDebugApp()");
9711
9712        long ident = Binder.clearCallingIdentity();
9713        try {
9714            // Note that this is not really thread safe if there are multiple
9715            // callers into it at the same time, but that's not a situation we
9716            // care about.
9717            if (persistent) {
9718                final ContentResolver resolver = mContext.getContentResolver();
9719                Settings.Global.putString(
9720                    resolver, Settings.Global.DEBUG_APP,
9721                    packageName);
9722                Settings.Global.putInt(
9723                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9724                    waitForDebugger ? 1 : 0);
9725            }
9726
9727            synchronized (this) {
9728                if (!persistent) {
9729                    mOrigDebugApp = mDebugApp;
9730                    mOrigWaitForDebugger = mWaitForDebugger;
9731                }
9732                mDebugApp = packageName;
9733                mWaitForDebugger = waitForDebugger;
9734                mDebugTransient = !persistent;
9735                if (packageName != null) {
9736                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9737                            false, UserHandle.USER_ALL, "set debug app");
9738                }
9739            }
9740        } finally {
9741            Binder.restoreCallingIdentity(ident);
9742        }
9743    }
9744
9745    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9746        synchronized (this) {
9747            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9748            if (!isDebuggable) {
9749                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9750                    throw new SecurityException("Process not debuggable: " + app.packageName);
9751                }
9752            }
9753
9754            mOpenGlTraceApp = processName;
9755        }
9756    }
9757
9758    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
9759        synchronized (this) {
9760            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9761            if (!isDebuggable) {
9762                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9763                    throw new SecurityException("Process not debuggable: " + app.packageName);
9764                }
9765            }
9766            mProfileApp = processName;
9767            mProfileFile = profilerInfo.profileFile;
9768            if (mProfileFd != null) {
9769                try {
9770                    mProfileFd.close();
9771                } catch (IOException e) {
9772                }
9773                mProfileFd = null;
9774            }
9775            mProfileFd = profilerInfo.profileFd;
9776            mSamplingInterval = profilerInfo.samplingInterval;
9777            mAutoStopProfiler = profilerInfo.autoStopProfiler;
9778            mProfileType = 0;
9779        }
9780    }
9781
9782    @Override
9783    public void setAlwaysFinish(boolean enabled) {
9784        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9785                "setAlwaysFinish()");
9786
9787        Settings.Global.putInt(
9788                mContext.getContentResolver(),
9789                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9790
9791        synchronized (this) {
9792            mAlwaysFinishActivities = enabled;
9793        }
9794    }
9795
9796    @Override
9797    public void setActivityController(IActivityController controller) {
9798        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9799                "setActivityController()");
9800        synchronized (this) {
9801            mController = controller;
9802            Watchdog.getInstance().setActivityController(controller);
9803        }
9804    }
9805
9806    @Override
9807    public void setUserIsMonkey(boolean userIsMonkey) {
9808        synchronized (this) {
9809            synchronized (mPidsSelfLocked) {
9810                final int callingPid = Binder.getCallingPid();
9811                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9812                if (precessRecord == null) {
9813                    throw new SecurityException("Unknown process: " + callingPid);
9814                }
9815                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9816                    throw new SecurityException("Only an instrumentation process "
9817                            + "with a UiAutomation can call setUserIsMonkey");
9818                }
9819            }
9820            mUserIsMonkey = userIsMonkey;
9821        }
9822    }
9823
9824    @Override
9825    public boolean isUserAMonkey() {
9826        synchronized (this) {
9827            // If there is a controller also implies the user is a monkey.
9828            return (mUserIsMonkey || mController != null);
9829        }
9830    }
9831
9832    public void requestBugReport() {
9833        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9834        SystemProperties.set("ctl.start", "bugreport");
9835    }
9836
9837    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9838        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9839    }
9840
9841    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9842        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9843            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9844        }
9845        return KEY_DISPATCHING_TIMEOUT;
9846    }
9847
9848    @Override
9849    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9850        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9851                != PackageManager.PERMISSION_GRANTED) {
9852            throw new SecurityException("Requires permission "
9853                    + android.Manifest.permission.FILTER_EVENTS);
9854        }
9855        ProcessRecord proc;
9856        long timeout;
9857        synchronized (this) {
9858            synchronized (mPidsSelfLocked) {
9859                proc = mPidsSelfLocked.get(pid);
9860            }
9861            timeout = getInputDispatchingTimeoutLocked(proc);
9862        }
9863
9864        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9865            return -1;
9866        }
9867
9868        return timeout;
9869    }
9870
9871    /**
9872     * Handle input dispatching timeouts.
9873     * Returns whether input dispatching should be aborted or not.
9874     */
9875    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9876            final ActivityRecord activity, final ActivityRecord parent,
9877            final boolean aboveSystem, String reason) {
9878        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9879                != PackageManager.PERMISSION_GRANTED) {
9880            throw new SecurityException("Requires permission "
9881                    + android.Manifest.permission.FILTER_EVENTS);
9882        }
9883
9884        final String annotation;
9885        if (reason == null) {
9886            annotation = "Input dispatching timed out";
9887        } else {
9888            annotation = "Input dispatching timed out (" + reason + ")";
9889        }
9890
9891        if (proc != null) {
9892            synchronized (this) {
9893                if (proc.debugging) {
9894                    return false;
9895                }
9896
9897                if (mDidDexOpt) {
9898                    // Give more time since we were dexopting.
9899                    mDidDexOpt = false;
9900                    return false;
9901                }
9902
9903                if (proc.instrumentationClass != null) {
9904                    Bundle info = new Bundle();
9905                    info.putString("shortMsg", "keyDispatchingTimedOut");
9906                    info.putString("longMsg", annotation);
9907                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9908                    return true;
9909                }
9910            }
9911            mHandler.post(new Runnable() {
9912                @Override
9913                public void run() {
9914                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9915                }
9916            });
9917        }
9918
9919        return true;
9920    }
9921
9922    public Bundle getAssistContextExtras(int requestType) {
9923        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
9924                UserHandle.getCallingUserId());
9925        if (pae == null) {
9926            return null;
9927        }
9928        synchronized (pae) {
9929            while (!pae.haveResult) {
9930                try {
9931                    pae.wait();
9932                } catch (InterruptedException e) {
9933                }
9934            }
9935            if (pae.result != null) {
9936                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9937            }
9938        }
9939        synchronized (this) {
9940            mPendingAssistExtras.remove(pae);
9941            mHandler.removeCallbacks(pae);
9942        }
9943        return pae.extras;
9944    }
9945
9946    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
9947            int userHandle) {
9948        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9949                "getAssistContextExtras()");
9950        PendingAssistExtras pae;
9951        Bundle extras = new Bundle();
9952        synchronized (this) {
9953            ActivityRecord activity = getFocusedStack().mResumedActivity;
9954            if (activity == null) {
9955                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9956                return null;
9957            }
9958            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9959            if (activity.app == null || activity.app.thread == null) {
9960                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9961                return null;
9962            }
9963            if (activity.app.pid == Binder.getCallingPid()) {
9964                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9965                return null;
9966            }
9967            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
9968            try {
9969                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9970                        requestType);
9971                mPendingAssistExtras.add(pae);
9972                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9973            } catch (RemoteException e) {
9974                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9975                return null;
9976            }
9977            return pae;
9978        }
9979    }
9980
9981    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9982        PendingAssistExtras pae = (PendingAssistExtras)token;
9983        synchronized (pae) {
9984            pae.result = extras;
9985            pae.haveResult = true;
9986            pae.notifyAll();
9987            if (pae.intent == null) {
9988                // Caller is just waiting for the result.
9989                return;
9990            }
9991        }
9992
9993        // We are now ready to launch the assist activity.
9994        synchronized (this) {
9995            boolean exists = mPendingAssistExtras.remove(pae);
9996            mHandler.removeCallbacks(pae);
9997            if (!exists) {
9998                // Timed out.
9999                return;
10000            }
10001        }
10002        pae.intent.replaceExtras(extras);
10003        if (pae.hint != null) {
10004            pae.intent.putExtra(pae.hint, true);
10005        }
10006        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10007                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10008                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10009        closeSystemDialogs("assist");
10010        try {
10011            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10012        } catch (ActivityNotFoundException e) {
10013            Slog.w(TAG, "No activity to handle assist action.", e);
10014        }
10015    }
10016
10017    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10018        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10019    }
10020
10021    public void registerProcessObserver(IProcessObserver observer) {
10022        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10023                "registerProcessObserver()");
10024        synchronized (this) {
10025            mProcessObservers.register(observer);
10026        }
10027    }
10028
10029    @Override
10030    public void unregisterProcessObserver(IProcessObserver observer) {
10031        synchronized (this) {
10032            mProcessObservers.unregister(observer);
10033        }
10034    }
10035
10036    @Override
10037    public boolean convertFromTranslucent(IBinder token) {
10038        final long origId = Binder.clearCallingIdentity();
10039        try {
10040            synchronized (this) {
10041                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10042                if (r == null) {
10043                    return false;
10044                }
10045                final boolean translucentChanged = r.changeWindowTranslucency(true);
10046                if (translucentChanged) {
10047                    r.task.stack.releaseBackgroundResources(r);
10048                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10049                }
10050                mWindowManager.setAppFullscreen(token, true);
10051                return translucentChanged;
10052            }
10053        } finally {
10054            Binder.restoreCallingIdentity(origId);
10055        }
10056    }
10057
10058    @Override
10059    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10060        final long origId = Binder.clearCallingIdentity();
10061        try {
10062            synchronized (this) {
10063                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10064                if (r == null) {
10065                    return false;
10066                }
10067                int index = r.task.mActivities.lastIndexOf(r);
10068                if (index > 0) {
10069                    ActivityRecord under = r.task.mActivities.get(index - 1);
10070                    under.returningOptions = options;
10071                }
10072                final boolean translucentChanged = r.changeWindowTranslucency(false);
10073                if (translucentChanged) {
10074                    r.task.stack.convertActivityToTranslucent(r);
10075                }
10076                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10077                mWindowManager.setAppFullscreen(token, false);
10078                return translucentChanged;
10079            }
10080        } finally {
10081            Binder.restoreCallingIdentity(origId);
10082        }
10083    }
10084
10085    @Override
10086    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10087        final long origId = Binder.clearCallingIdentity();
10088        try {
10089            synchronized (this) {
10090                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10091                if (r != null) {
10092                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10093                }
10094            }
10095            return false;
10096        } finally {
10097            Binder.restoreCallingIdentity(origId);
10098        }
10099    }
10100
10101    @Override
10102    public boolean isBackgroundVisibleBehind(IBinder token) {
10103        final long origId = Binder.clearCallingIdentity();
10104        try {
10105            synchronized (this) {
10106                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10107                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10108                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10109                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10110                return visible;
10111            }
10112        } finally {
10113            Binder.restoreCallingIdentity(origId);
10114        }
10115    }
10116
10117    @Override
10118    public ActivityOptions getActivityOptions(IBinder token) {
10119        final long origId = Binder.clearCallingIdentity();
10120        try {
10121            synchronized (this) {
10122                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10123                if (r != null) {
10124                    final ActivityOptions activityOptions = r.pendingOptions;
10125                    r.pendingOptions = null;
10126                    return activityOptions;
10127                }
10128                return null;
10129            }
10130        } finally {
10131            Binder.restoreCallingIdentity(origId);
10132        }
10133    }
10134
10135    @Override
10136    public void setImmersive(IBinder token, boolean immersive) {
10137        synchronized(this) {
10138            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10139            if (r == null) {
10140                throw new IllegalArgumentException();
10141            }
10142            r.immersive = immersive;
10143
10144            // update associated state if we're frontmost
10145            if (r == mFocusedActivity) {
10146                if (DEBUG_IMMERSIVE) {
10147                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10148                }
10149                applyUpdateLockStateLocked(r);
10150            }
10151        }
10152    }
10153
10154    @Override
10155    public boolean isImmersive(IBinder token) {
10156        synchronized (this) {
10157            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10158            if (r == null) {
10159                throw new IllegalArgumentException();
10160            }
10161            return r.immersive;
10162        }
10163    }
10164
10165    public boolean isTopActivityImmersive() {
10166        enforceNotIsolatedCaller("startActivity");
10167        synchronized (this) {
10168            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10169            return (r != null) ? r.immersive : false;
10170        }
10171    }
10172
10173    @Override
10174    public boolean isTopOfTask(IBinder token) {
10175        synchronized (this) {
10176            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10177            if (r == null) {
10178                throw new IllegalArgumentException();
10179            }
10180            return r.task.getTopActivity() == r;
10181        }
10182    }
10183
10184    public final void enterSafeMode() {
10185        synchronized(this) {
10186            // It only makes sense to do this before the system is ready
10187            // and started launching other packages.
10188            if (!mSystemReady) {
10189                try {
10190                    AppGlobals.getPackageManager().enterSafeMode();
10191                } catch (RemoteException e) {
10192                }
10193            }
10194
10195            mSafeMode = true;
10196        }
10197    }
10198
10199    public final void showSafeModeOverlay() {
10200        View v = LayoutInflater.from(mContext).inflate(
10201                com.android.internal.R.layout.safe_mode, null);
10202        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10203        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10204        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10205        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10206        lp.gravity = Gravity.BOTTOM | Gravity.START;
10207        lp.format = v.getBackground().getOpacity();
10208        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10209                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10210        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10211        ((WindowManager)mContext.getSystemService(
10212                Context.WINDOW_SERVICE)).addView(v, lp);
10213    }
10214
10215    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10216        if (!(sender instanceof PendingIntentRecord)) {
10217            return;
10218        }
10219        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10220        synchronized (stats) {
10221            if (mBatteryStatsService.isOnBattery()) {
10222                mBatteryStatsService.enforceCallingPermission();
10223                PendingIntentRecord rec = (PendingIntentRecord)sender;
10224                int MY_UID = Binder.getCallingUid();
10225                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10226                BatteryStatsImpl.Uid.Pkg pkg =
10227                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10228                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10229                pkg.incWakeupsLocked();
10230            }
10231        }
10232    }
10233
10234    public boolean killPids(int[] pids, String pReason, boolean secure) {
10235        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10236            throw new SecurityException("killPids only available to the system");
10237        }
10238        String reason = (pReason == null) ? "Unknown" : pReason;
10239        // XXX Note: don't acquire main activity lock here, because the window
10240        // manager calls in with its locks held.
10241
10242        boolean killed = false;
10243        synchronized (mPidsSelfLocked) {
10244            int[] types = new int[pids.length];
10245            int worstType = 0;
10246            for (int i=0; i<pids.length; i++) {
10247                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10248                if (proc != null) {
10249                    int type = proc.setAdj;
10250                    types[i] = type;
10251                    if (type > worstType) {
10252                        worstType = type;
10253                    }
10254                }
10255            }
10256
10257            // If the worst oom_adj is somewhere in the cached proc LRU range,
10258            // then constrain it so we will kill all cached procs.
10259            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10260                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10261                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10262            }
10263
10264            // If this is not a secure call, don't let it kill processes that
10265            // are important.
10266            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10267                worstType = ProcessList.SERVICE_ADJ;
10268            }
10269
10270            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10271            for (int i=0; i<pids.length; i++) {
10272                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10273                if (proc == null) {
10274                    continue;
10275                }
10276                int adj = proc.setAdj;
10277                if (adj >= worstType && !proc.killedByAm) {
10278                    proc.kill(reason, true);
10279                    killed = true;
10280                }
10281            }
10282        }
10283        return killed;
10284    }
10285
10286    @Override
10287    public void killUid(int uid, String reason) {
10288        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10289            throw new SecurityException("killUid only available to the system");
10290        }
10291        synchronized (this) {
10292            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10293                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10294                    reason != null ? reason : "kill uid");
10295        }
10296    }
10297
10298    @Override
10299    public boolean killProcessesBelowForeground(String reason) {
10300        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10301            throw new SecurityException("killProcessesBelowForeground() only available to system");
10302        }
10303
10304        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10305    }
10306
10307    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10308        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10309            throw new SecurityException("killProcessesBelowAdj() only available to system");
10310        }
10311
10312        boolean killed = false;
10313        synchronized (mPidsSelfLocked) {
10314            final int size = mPidsSelfLocked.size();
10315            for (int i = 0; i < size; i++) {
10316                final int pid = mPidsSelfLocked.keyAt(i);
10317                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10318                if (proc == null) continue;
10319
10320                final int adj = proc.setAdj;
10321                if (adj > belowAdj && !proc.killedByAm) {
10322                    proc.kill(reason, true);
10323                    killed = true;
10324                }
10325            }
10326        }
10327        return killed;
10328    }
10329
10330    @Override
10331    public void hang(final IBinder who, boolean allowRestart) {
10332        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10333                != PackageManager.PERMISSION_GRANTED) {
10334            throw new SecurityException("Requires permission "
10335                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10336        }
10337
10338        final IBinder.DeathRecipient death = new DeathRecipient() {
10339            @Override
10340            public void binderDied() {
10341                synchronized (this) {
10342                    notifyAll();
10343                }
10344            }
10345        };
10346
10347        try {
10348            who.linkToDeath(death, 0);
10349        } catch (RemoteException e) {
10350            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10351            return;
10352        }
10353
10354        synchronized (this) {
10355            Watchdog.getInstance().setAllowRestart(allowRestart);
10356            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10357            synchronized (death) {
10358                while (who.isBinderAlive()) {
10359                    try {
10360                        death.wait();
10361                    } catch (InterruptedException e) {
10362                    }
10363                }
10364            }
10365            Watchdog.getInstance().setAllowRestart(true);
10366        }
10367    }
10368
10369    @Override
10370    public void restart() {
10371        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10372                != PackageManager.PERMISSION_GRANTED) {
10373            throw new SecurityException("Requires permission "
10374                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10375        }
10376
10377        Log.i(TAG, "Sending shutdown broadcast...");
10378
10379        BroadcastReceiver br = new BroadcastReceiver() {
10380            @Override public void onReceive(Context context, Intent intent) {
10381                // Now the broadcast is done, finish up the low-level shutdown.
10382                Log.i(TAG, "Shutting down activity manager...");
10383                shutdown(10000);
10384                Log.i(TAG, "Shutdown complete, restarting!");
10385                Process.killProcess(Process.myPid());
10386                System.exit(10);
10387            }
10388        };
10389
10390        // First send the high-level shut down broadcast.
10391        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10392        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10393        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10394        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10395        mContext.sendOrderedBroadcastAsUser(intent,
10396                UserHandle.ALL, null, br, mHandler, 0, null, null);
10397        */
10398        br.onReceive(mContext, intent);
10399    }
10400
10401    private long getLowRamTimeSinceIdle(long now) {
10402        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10403    }
10404
10405    @Override
10406    public void performIdleMaintenance() {
10407        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10408                != PackageManager.PERMISSION_GRANTED) {
10409            throw new SecurityException("Requires permission "
10410                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10411        }
10412
10413        synchronized (this) {
10414            final long now = SystemClock.uptimeMillis();
10415            final long timeSinceLastIdle = now - mLastIdleTime;
10416            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10417            mLastIdleTime = now;
10418            mLowRamTimeSinceLastIdle = 0;
10419            if (mLowRamStartTime != 0) {
10420                mLowRamStartTime = now;
10421            }
10422
10423            StringBuilder sb = new StringBuilder(128);
10424            sb.append("Idle maintenance over ");
10425            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10426            sb.append(" low RAM for ");
10427            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10428            Slog.i(TAG, sb.toString());
10429
10430            // If at least 1/3 of our time since the last idle period has been spent
10431            // with RAM low, then we want to kill processes.
10432            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10433
10434            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10435                ProcessRecord proc = mLruProcesses.get(i);
10436                if (proc.notCachedSinceIdle) {
10437                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10438                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10439                        if (doKilling && proc.initialIdlePss != 0
10440                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10441                            sb = new StringBuilder(128);
10442                            sb.append("Kill");
10443                            sb.append(proc.processName);
10444                            sb.append(" in idle maint: pss=");
10445                            sb.append(proc.lastPss);
10446                            sb.append(", initialPss=");
10447                            sb.append(proc.initialIdlePss);
10448                            sb.append(", period=");
10449                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10450                            sb.append(", lowRamPeriod=");
10451                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10452                            Slog.wtfQuiet(TAG, sb.toString());
10453                            proc.kill("idle maint (pss " + proc.lastPss
10454                                    + " from " + proc.initialIdlePss + ")", true);
10455                        }
10456                    }
10457                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10458                    proc.notCachedSinceIdle = true;
10459                    proc.initialIdlePss = 0;
10460                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10461                            mTestPssMode, isSleeping(), now);
10462                }
10463            }
10464
10465            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10466            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10467        }
10468    }
10469
10470    private void retrieveSettings() {
10471        final ContentResolver resolver = mContext.getContentResolver();
10472        String debugApp = Settings.Global.getString(
10473            resolver, Settings.Global.DEBUG_APP);
10474        boolean waitForDebugger = Settings.Global.getInt(
10475            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10476        boolean alwaysFinishActivities = Settings.Global.getInt(
10477            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10478        boolean forceRtl = Settings.Global.getInt(
10479                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10480        // Transfer any global setting for forcing RTL layout, into a System Property
10481        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10482
10483        Configuration configuration = new Configuration();
10484        Settings.System.getConfiguration(resolver, configuration);
10485        if (forceRtl) {
10486            // This will take care of setting the correct layout direction flags
10487            configuration.setLayoutDirection(configuration.locale);
10488        }
10489
10490        synchronized (this) {
10491            mDebugApp = mOrigDebugApp = debugApp;
10492            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10493            mAlwaysFinishActivities = alwaysFinishActivities;
10494            // This happens before any activities are started, so we can
10495            // change mConfiguration in-place.
10496            updateConfigurationLocked(configuration, null, false, true);
10497            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10498        }
10499    }
10500
10501    /** Loads resources after the current configuration has been set. */
10502    private void loadResourcesOnSystemReady() {
10503        final Resources res = mContext.getResources();
10504        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10505        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10506        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10507    }
10508
10509    public boolean testIsSystemReady() {
10510        // no need to synchronize(this) just to read & return the value
10511        return mSystemReady;
10512    }
10513
10514    private static File getCalledPreBootReceiversFile() {
10515        File dataDir = Environment.getDataDirectory();
10516        File systemDir = new File(dataDir, "system");
10517        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10518        return fname;
10519    }
10520
10521    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10522        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10523        File file = getCalledPreBootReceiversFile();
10524        FileInputStream fis = null;
10525        try {
10526            fis = new FileInputStream(file);
10527            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10528            int fvers = dis.readInt();
10529            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10530                String vers = dis.readUTF();
10531                String codename = dis.readUTF();
10532                String build = dis.readUTF();
10533                if (android.os.Build.VERSION.RELEASE.equals(vers)
10534                        && android.os.Build.VERSION.CODENAME.equals(codename)
10535                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10536                    int num = dis.readInt();
10537                    while (num > 0) {
10538                        num--;
10539                        String pkg = dis.readUTF();
10540                        String cls = dis.readUTF();
10541                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10542                    }
10543                }
10544            }
10545        } catch (FileNotFoundException e) {
10546        } catch (IOException e) {
10547            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10548        } finally {
10549            if (fis != null) {
10550                try {
10551                    fis.close();
10552                } catch (IOException e) {
10553                }
10554            }
10555        }
10556        return lastDoneReceivers;
10557    }
10558
10559    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10560        File file = getCalledPreBootReceiversFile();
10561        FileOutputStream fos = null;
10562        DataOutputStream dos = null;
10563        try {
10564            fos = new FileOutputStream(file);
10565            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10566            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10567            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10568            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10569            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10570            dos.writeInt(list.size());
10571            for (int i=0; i<list.size(); i++) {
10572                dos.writeUTF(list.get(i).getPackageName());
10573                dos.writeUTF(list.get(i).getClassName());
10574            }
10575        } catch (IOException e) {
10576            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10577            file.delete();
10578        } finally {
10579            FileUtils.sync(fos);
10580            if (dos != null) {
10581                try {
10582                    dos.close();
10583                } catch (IOException e) {
10584                    // TODO Auto-generated catch block
10585                    e.printStackTrace();
10586                }
10587            }
10588        }
10589    }
10590
10591    final class PreBootContinuation extends IIntentReceiver.Stub {
10592        final Intent intent;
10593        final Runnable onFinishCallback;
10594        final ArrayList<ComponentName> doneReceivers;
10595        final List<ResolveInfo> ris;
10596        final int[] users;
10597        int lastRi = -1;
10598        int curRi = 0;
10599        int curUser = 0;
10600
10601        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
10602                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
10603            intent = _intent;
10604            onFinishCallback = _onFinishCallback;
10605            doneReceivers = _doneReceivers;
10606            ris = _ris;
10607            users = _users;
10608        }
10609
10610        void go() {
10611            if (lastRi != curRi) {
10612                ActivityInfo ai = ris.get(curRi).activityInfo;
10613                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10614                intent.setComponent(comp);
10615                doneReceivers.add(comp);
10616                lastRi = curRi;
10617                CharSequence label = ai.loadLabel(mContext.getPackageManager());
10618                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
10619            }
10620            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
10621                    + " for user " + users[curUser]);
10622            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
10623            broadcastIntentLocked(null, null, intent, null, this,
10624                    0, null, null, null, AppOpsManager.OP_NONE,
10625                    true, false, MY_PID, Process.SYSTEM_UID,
10626                    users[curUser]);
10627        }
10628
10629        public void performReceive(Intent intent, int resultCode,
10630                String data, Bundle extras, boolean ordered,
10631                boolean sticky, int sendingUser) {
10632            curUser++;
10633            if (curUser >= users.length) {
10634                curUser = 0;
10635                curRi++;
10636                if (curRi >= ris.size()) {
10637                    // All done sending broadcasts!
10638                    if (onFinishCallback != null) {
10639                        // The raw IIntentReceiver interface is called
10640                        // with the AM lock held, so redispatch to
10641                        // execute our code without the lock.
10642                        mHandler.post(onFinishCallback);
10643                    }
10644                    return;
10645                }
10646            }
10647            go();
10648        }
10649    }
10650
10651    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10652            ArrayList<ComponentName> doneReceivers, int userId) {
10653        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10654        List<ResolveInfo> ris = null;
10655        try {
10656            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10657                    intent, null, 0, userId);
10658        } catch (RemoteException e) {
10659        }
10660        if (ris == null) {
10661            return false;
10662        }
10663        for (int i=ris.size()-1; i>=0; i--) {
10664            if ((ris.get(i).activityInfo.applicationInfo.flags
10665                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
10666                ris.remove(i);
10667            }
10668        }
10669        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10670
10671        // For User 0, load the version number. When delivering to a new user, deliver
10672        // to all receivers.
10673        if (userId == UserHandle.USER_OWNER) {
10674            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10675            for (int i=0; i<ris.size(); i++) {
10676                ActivityInfo ai = ris.get(i).activityInfo;
10677                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10678                if (false && lastDoneReceivers.contains(comp)) {
10679                    // We already did the pre boot receiver for this app with the current
10680                    // platform version, so don't do it again...
10681                    ris.remove(i);
10682                    i--;
10683                    // ...however, do keep it as one that has been done, so we don't
10684                    // forget about it when rewriting the file of last done receivers.
10685                    doneReceivers.add(comp);
10686                }
10687            }
10688        }
10689
10690        if (ris.size() <= 0) {
10691            return false;
10692        }
10693
10694        // If primary user, send broadcast to all available users, else just to userId
10695        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10696                : new int[] { userId };
10697        if (users.length <= 0) {
10698            return false;
10699        }
10700
10701        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
10702                ris, users);
10703        cont.go();
10704        return true;
10705    }
10706
10707    public void systemReady(final Runnable goingCallback) {
10708        synchronized(this) {
10709            if (mSystemReady) {
10710                // If we're done calling all the receivers, run the next "boot phase" passed in
10711                // by the SystemServer
10712                if (goingCallback != null) {
10713                    goingCallback.run();
10714                }
10715                return;
10716            }
10717
10718            // Make sure we have the current profile info, since it is needed for
10719            // security checks.
10720            updateCurrentProfileIdsLocked();
10721
10722            mRecentTasks.clear();
10723            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
10724            mTaskPersister.restoreTasksFromOtherDeviceLocked();
10725            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
10726            mTaskPersister.startPersisting();
10727
10728            // Check to see if there are any update receivers to run.
10729            if (!mDidUpdate) {
10730                if (mWaitingUpdate) {
10731                    return;
10732                }
10733                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10734                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10735                    public void run() {
10736                        synchronized (ActivityManagerService.this) {
10737                            mDidUpdate = true;
10738                        }
10739                        showBootMessage(mContext.getText(
10740                                R.string.android_upgrading_complete),
10741                                false);
10742                        writeLastDonePreBootReceivers(doneReceivers);
10743                        systemReady(goingCallback);
10744                    }
10745                }, doneReceivers, UserHandle.USER_OWNER);
10746
10747                if (mWaitingUpdate) {
10748                    return;
10749                }
10750                mDidUpdate = true;
10751            }
10752
10753            mAppOpsService.systemReady();
10754            mSystemReady = true;
10755        }
10756
10757        ArrayList<ProcessRecord> procsToKill = null;
10758        synchronized(mPidsSelfLocked) {
10759            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10760                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10761                if (!isAllowedWhileBooting(proc.info)){
10762                    if (procsToKill == null) {
10763                        procsToKill = new ArrayList<ProcessRecord>();
10764                    }
10765                    procsToKill.add(proc);
10766                }
10767            }
10768        }
10769
10770        synchronized(this) {
10771            if (procsToKill != null) {
10772                for (int i=procsToKill.size()-1; i>=0; i--) {
10773                    ProcessRecord proc = procsToKill.get(i);
10774                    Slog.i(TAG, "Removing system update proc: " + proc);
10775                    removeProcessLocked(proc, true, false, "system update done");
10776                }
10777            }
10778
10779            // Now that we have cleaned up any update processes, we
10780            // are ready to start launching real processes and know that
10781            // we won't trample on them any more.
10782            mProcessesReady = true;
10783        }
10784
10785        Slog.i(TAG, "System now ready");
10786        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10787            SystemClock.uptimeMillis());
10788
10789        synchronized(this) {
10790            // Make sure we have no pre-ready processes sitting around.
10791
10792            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10793                ResolveInfo ri = mContext.getPackageManager()
10794                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10795                                STOCK_PM_FLAGS);
10796                CharSequence errorMsg = null;
10797                if (ri != null) {
10798                    ActivityInfo ai = ri.activityInfo;
10799                    ApplicationInfo app = ai.applicationInfo;
10800                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10801                        mTopAction = Intent.ACTION_FACTORY_TEST;
10802                        mTopData = null;
10803                        mTopComponent = new ComponentName(app.packageName,
10804                                ai.name);
10805                    } else {
10806                        errorMsg = mContext.getResources().getText(
10807                                com.android.internal.R.string.factorytest_not_system);
10808                    }
10809                } else {
10810                    errorMsg = mContext.getResources().getText(
10811                            com.android.internal.R.string.factorytest_no_action);
10812                }
10813                if (errorMsg != null) {
10814                    mTopAction = null;
10815                    mTopData = null;
10816                    mTopComponent = null;
10817                    Message msg = Message.obtain();
10818                    msg.what = SHOW_FACTORY_ERROR_MSG;
10819                    msg.getData().putCharSequence("msg", errorMsg);
10820                    mHandler.sendMessage(msg);
10821                }
10822            }
10823        }
10824
10825        retrieveSettings();
10826        loadResourcesOnSystemReady();
10827
10828        synchronized (this) {
10829            readGrantedUriPermissionsLocked();
10830        }
10831
10832        if (goingCallback != null) goingCallback.run();
10833
10834        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10835                Integer.toString(mCurrentUserId), mCurrentUserId);
10836        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10837                Integer.toString(mCurrentUserId), mCurrentUserId);
10838        mSystemServiceManager.startUser(mCurrentUserId);
10839
10840        synchronized (this) {
10841            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10842                try {
10843                    List apps = AppGlobals.getPackageManager().
10844                        getPersistentApplications(STOCK_PM_FLAGS);
10845                    if (apps != null) {
10846                        int N = apps.size();
10847                        int i;
10848                        for (i=0; i<N; i++) {
10849                            ApplicationInfo info
10850                                = (ApplicationInfo)apps.get(i);
10851                            if (info != null &&
10852                                    !info.packageName.equals("android")) {
10853                                addAppLocked(info, false, null /* ABI override */);
10854                            }
10855                        }
10856                    }
10857                } catch (RemoteException ex) {
10858                    // pm is in same process, this will never happen.
10859                }
10860            }
10861
10862            // Start up initial activity.
10863            mBooting = true;
10864            startHomeActivityLocked(mCurrentUserId, "systemReady");
10865
10866            try {
10867                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10868                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
10869                            + " data partition or your device will be unstable.");
10870                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
10871                }
10872            } catch (RemoteException e) {
10873            }
10874
10875            if (!Build.isFingerprintConsistent()) {
10876                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
10877                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
10878            }
10879
10880            long ident = Binder.clearCallingIdentity();
10881            try {
10882                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10883                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10884                        | Intent.FLAG_RECEIVER_FOREGROUND);
10885                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10886                broadcastIntentLocked(null, null, intent,
10887                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10888                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10889                intent = new Intent(Intent.ACTION_USER_STARTING);
10890                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10891                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10892                broadcastIntentLocked(null, null, intent,
10893                        null, new IIntentReceiver.Stub() {
10894                            @Override
10895                            public void performReceive(Intent intent, int resultCode, String data,
10896                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10897                                    throws RemoteException {
10898                            }
10899                        }, 0, null, null,
10900                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10901                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10902            } catch (Throwable t) {
10903                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10904            } finally {
10905                Binder.restoreCallingIdentity(ident);
10906            }
10907            mStackSupervisor.resumeTopActivitiesLocked();
10908            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10909        }
10910    }
10911
10912    private boolean makeAppCrashingLocked(ProcessRecord app,
10913            String shortMsg, String longMsg, String stackTrace) {
10914        app.crashing = true;
10915        app.crashingReport = generateProcessError(app,
10916                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10917        startAppProblemLocked(app);
10918        app.stopFreezingAllLocked();
10919        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
10920    }
10921
10922    private void makeAppNotRespondingLocked(ProcessRecord app,
10923            String activity, String shortMsg, String longMsg) {
10924        app.notResponding = true;
10925        app.notRespondingReport = generateProcessError(app,
10926                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10927                activity, shortMsg, longMsg, null);
10928        startAppProblemLocked(app);
10929        app.stopFreezingAllLocked();
10930    }
10931
10932    /**
10933     * Generate a process error record, suitable for attachment to a ProcessRecord.
10934     *
10935     * @param app The ProcessRecord in which the error occurred.
10936     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10937     *                      ActivityManager.AppErrorStateInfo
10938     * @param activity The activity associated with the crash, if known.
10939     * @param shortMsg Short message describing the crash.
10940     * @param longMsg Long message describing the crash.
10941     * @param stackTrace Full crash stack trace, may be null.
10942     *
10943     * @return Returns a fully-formed AppErrorStateInfo record.
10944     */
10945    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10946            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10947        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10948
10949        report.condition = condition;
10950        report.processName = app.processName;
10951        report.pid = app.pid;
10952        report.uid = app.info.uid;
10953        report.tag = activity;
10954        report.shortMsg = shortMsg;
10955        report.longMsg = longMsg;
10956        report.stackTrace = stackTrace;
10957
10958        return report;
10959    }
10960
10961    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10962        synchronized (this) {
10963            app.crashing = false;
10964            app.crashingReport = null;
10965            app.notResponding = false;
10966            app.notRespondingReport = null;
10967            if (app.anrDialog == fromDialog) {
10968                app.anrDialog = null;
10969            }
10970            if (app.waitDialog == fromDialog) {
10971                app.waitDialog = null;
10972            }
10973            if (app.pid > 0 && app.pid != MY_PID) {
10974                handleAppCrashLocked(app, "user-terminated" /*reason*/,
10975                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
10976                app.kill("user request after error", true);
10977            }
10978        }
10979    }
10980
10981    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
10982            String shortMsg, String longMsg, String stackTrace) {
10983        long now = SystemClock.uptimeMillis();
10984
10985        Long crashTime;
10986        if (!app.isolated) {
10987            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10988        } else {
10989            crashTime = null;
10990        }
10991        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10992            // This process loses!
10993            Slog.w(TAG, "Process " + app.info.processName
10994                    + " has crashed too many times: killing!");
10995            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10996                    app.userId, app.info.processName, app.uid);
10997            mStackSupervisor.handleAppCrashLocked(app);
10998            if (!app.persistent) {
10999                // We don't want to start this process again until the user
11000                // explicitly does so...  but for persistent process, we really
11001                // need to keep it running.  If a persistent process is actually
11002                // repeatedly crashing, then badness for everyone.
11003                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11004                        app.info.processName);
11005                if (!app.isolated) {
11006                    // XXX We don't have a way to mark isolated processes
11007                    // as bad, since they don't have a peristent identity.
11008                    mBadProcesses.put(app.info.processName, app.uid,
11009                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11010                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11011                }
11012                app.bad = true;
11013                app.removed = true;
11014                // Don't let services in this process be restarted and potentially
11015                // annoy the user repeatedly.  Unless it is persistent, since those
11016                // processes run critical code.
11017                removeProcessLocked(app, false, false, "crash");
11018                mStackSupervisor.resumeTopActivitiesLocked();
11019                return false;
11020            }
11021            mStackSupervisor.resumeTopActivitiesLocked();
11022        } else {
11023            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11024        }
11025
11026        // Bump up the crash count of any services currently running in the proc.
11027        for (int i=app.services.size()-1; i>=0; i--) {
11028            // Any services running in the application need to be placed
11029            // back in the pending list.
11030            ServiceRecord sr = app.services.valueAt(i);
11031            sr.crashCount++;
11032        }
11033
11034        // If the crashing process is what we consider to be the "home process" and it has been
11035        // replaced by a third-party app, clear the package preferred activities from packages
11036        // with a home activity running in the process to prevent a repeatedly crashing app
11037        // from blocking the user to manually clear the list.
11038        final ArrayList<ActivityRecord> activities = app.activities;
11039        if (app == mHomeProcess && activities.size() > 0
11040                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11041            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11042                final ActivityRecord r = activities.get(activityNdx);
11043                if (r.isHomeActivity()) {
11044                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11045                    try {
11046                        ActivityThread.getPackageManager()
11047                                .clearPackagePreferredActivities(r.packageName);
11048                    } catch (RemoteException c) {
11049                        // pm is in same process, this will never happen.
11050                    }
11051                }
11052            }
11053        }
11054
11055        if (!app.isolated) {
11056            // XXX Can't keep track of crash times for isolated processes,
11057            // because they don't have a perisistent identity.
11058            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11059        }
11060
11061        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11062        return true;
11063    }
11064
11065    void startAppProblemLocked(ProcessRecord app) {
11066        // If this app is not running under the current user, then we
11067        // can't give it a report button because that would require
11068        // launching the report UI under a different user.
11069        app.errorReportReceiver = null;
11070
11071        for (int userId : mCurrentProfileIds) {
11072            if (app.userId == userId) {
11073                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11074                        mContext, app.info.packageName, app.info.flags);
11075            }
11076        }
11077        skipCurrentReceiverLocked(app);
11078    }
11079
11080    void skipCurrentReceiverLocked(ProcessRecord app) {
11081        for (BroadcastQueue queue : mBroadcastQueues) {
11082            queue.skipCurrentReceiverLocked(app);
11083        }
11084    }
11085
11086    /**
11087     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11088     * The application process will exit immediately after this call returns.
11089     * @param app object of the crashing app, null for the system server
11090     * @param crashInfo describing the exception
11091     */
11092    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11093        ProcessRecord r = findAppProcess(app, "Crash");
11094        final String processName = app == null ? "system_server"
11095                : (r == null ? "unknown" : r.processName);
11096
11097        handleApplicationCrashInner("crash", r, processName, crashInfo);
11098    }
11099
11100    /* Native crash reporting uses this inner version because it needs to be somewhat
11101     * decoupled from the AM-managed cleanup lifecycle
11102     */
11103    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11104            ApplicationErrorReport.CrashInfo crashInfo) {
11105        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11106                UserHandle.getUserId(Binder.getCallingUid()), processName,
11107                r == null ? -1 : r.info.flags,
11108                crashInfo.exceptionClassName,
11109                crashInfo.exceptionMessage,
11110                crashInfo.throwFileName,
11111                crashInfo.throwLineNumber);
11112
11113        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11114
11115        crashApplication(r, crashInfo);
11116    }
11117
11118    public void handleApplicationStrictModeViolation(
11119            IBinder app,
11120            int violationMask,
11121            StrictMode.ViolationInfo info) {
11122        ProcessRecord r = findAppProcess(app, "StrictMode");
11123        if (r == null) {
11124            return;
11125        }
11126
11127        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11128            Integer stackFingerprint = info.hashCode();
11129            boolean logIt = true;
11130            synchronized (mAlreadyLoggedViolatedStacks) {
11131                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11132                    logIt = false;
11133                    // TODO: sub-sample into EventLog for these, with
11134                    // the info.durationMillis?  Then we'd get
11135                    // the relative pain numbers, without logging all
11136                    // the stack traces repeatedly.  We'd want to do
11137                    // likewise in the client code, which also does
11138                    // dup suppression, before the Binder call.
11139                } else {
11140                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11141                        mAlreadyLoggedViolatedStacks.clear();
11142                    }
11143                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11144                }
11145            }
11146            if (logIt) {
11147                logStrictModeViolationToDropBox(r, info);
11148            }
11149        }
11150
11151        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11152            AppErrorResult result = new AppErrorResult();
11153            synchronized (this) {
11154                final long origId = Binder.clearCallingIdentity();
11155
11156                Message msg = Message.obtain();
11157                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11158                HashMap<String, Object> data = new HashMap<String, Object>();
11159                data.put("result", result);
11160                data.put("app", r);
11161                data.put("violationMask", violationMask);
11162                data.put("info", info);
11163                msg.obj = data;
11164                mHandler.sendMessage(msg);
11165
11166                Binder.restoreCallingIdentity(origId);
11167            }
11168            int res = result.get();
11169            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11170        }
11171    }
11172
11173    // Depending on the policy in effect, there could be a bunch of
11174    // these in quick succession so we try to batch these together to
11175    // minimize disk writes, number of dropbox entries, and maximize
11176    // compression, by having more fewer, larger records.
11177    private void logStrictModeViolationToDropBox(
11178            ProcessRecord process,
11179            StrictMode.ViolationInfo info) {
11180        if (info == null) {
11181            return;
11182        }
11183        final boolean isSystemApp = process == null ||
11184                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11185                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11186        final String processName = process == null ? "unknown" : process.processName;
11187        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11188        final DropBoxManager dbox = (DropBoxManager)
11189                mContext.getSystemService(Context.DROPBOX_SERVICE);
11190
11191        // Exit early if the dropbox isn't configured to accept this report type.
11192        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11193
11194        boolean bufferWasEmpty;
11195        boolean needsFlush;
11196        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11197        synchronized (sb) {
11198            bufferWasEmpty = sb.length() == 0;
11199            appendDropBoxProcessHeaders(process, processName, sb);
11200            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11201            sb.append("System-App: ").append(isSystemApp).append("\n");
11202            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11203            if (info.violationNumThisLoop != 0) {
11204                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11205            }
11206            if (info.numAnimationsRunning != 0) {
11207                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11208            }
11209            if (info.broadcastIntentAction != null) {
11210                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11211            }
11212            if (info.durationMillis != -1) {
11213                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11214            }
11215            if (info.numInstances != -1) {
11216                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11217            }
11218            if (info.tags != null) {
11219                for (String tag : info.tags) {
11220                    sb.append("Span-Tag: ").append(tag).append("\n");
11221                }
11222            }
11223            sb.append("\n");
11224            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11225                sb.append(info.crashInfo.stackTrace);
11226                sb.append("\n");
11227            }
11228            if (info.message != null) {
11229                sb.append(info.message);
11230                sb.append("\n");
11231            }
11232
11233            // Only buffer up to ~64k.  Various logging bits truncate
11234            // things at 128k.
11235            needsFlush = (sb.length() > 64 * 1024);
11236        }
11237
11238        // Flush immediately if the buffer's grown too large, or this
11239        // is a non-system app.  Non-system apps are isolated with a
11240        // different tag & policy and not batched.
11241        //
11242        // Batching is useful during internal testing with
11243        // StrictMode settings turned up high.  Without batching,
11244        // thousands of separate files could be created on boot.
11245        if (!isSystemApp || needsFlush) {
11246            new Thread("Error dump: " + dropboxTag) {
11247                @Override
11248                public void run() {
11249                    String report;
11250                    synchronized (sb) {
11251                        report = sb.toString();
11252                        sb.delete(0, sb.length());
11253                        sb.trimToSize();
11254                    }
11255                    if (report.length() != 0) {
11256                        dbox.addText(dropboxTag, report);
11257                    }
11258                }
11259            }.start();
11260            return;
11261        }
11262
11263        // System app batching:
11264        if (!bufferWasEmpty) {
11265            // An existing dropbox-writing thread is outstanding, so
11266            // we don't need to start it up.  The existing thread will
11267            // catch the buffer appends we just did.
11268            return;
11269        }
11270
11271        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11272        // (After this point, we shouldn't access AMS internal data structures.)
11273        new Thread("Error dump: " + dropboxTag) {
11274            @Override
11275            public void run() {
11276                // 5 second sleep to let stacks arrive and be batched together
11277                try {
11278                    Thread.sleep(5000);  // 5 seconds
11279                } catch (InterruptedException e) {}
11280
11281                String errorReport;
11282                synchronized (mStrictModeBuffer) {
11283                    errorReport = mStrictModeBuffer.toString();
11284                    if (errorReport.length() == 0) {
11285                        return;
11286                    }
11287                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11288                    mStrictModeBuffer.trimToSize();
11289                }
11290                dbox.addText(dropboxTag, errorReport);
11291            }
11292        }.start();
11293    }
11294
11295    /**
11296     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11297     * @param app object of the crashing app, null for the system server
11298     * @param tag reported by the caller
11299     * @param system whether this wtf is coming from the system
11300     * @param crashInfo describing the context of the error
11301     * @return true if the process should exit immediately (WTF is fatal)
11302     */
11303    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11304            final ApplicationErrorReport.CrashInfo crashInfo) {
11305        final int callingUid = Binder.getCallingUid();
11306        final int callingPid = Binder.getCallingPid();
11307
11308        if (system) {
11309            // If this is coming from the system, we could very well have low-level
11310            // system locks held, so we want to do this all asynchronously.  And we
11311            // never want this to become fatal, so there is that too.
11312            mHandler.post(new Runnable() {
11313                @Override public void run() {
11314                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11315                }
11316            });
11317            return false;
11318        }
11319
11320        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11321                crashInfo);
11322
11323        if (r != null && r.pid != Process.myPid() &&
11324                Settings.Global.getInt(mContext.getContentResolver(),
11325                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11326            crashApplication(r, crashInfo);
11327            return true;
11328        } else {
11329            return false;
11330        }
11331    }
11332
11333    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11334            final ApplicationErrorReport.CrashInfo crashInfo) {
11335        final ProcessRecord r = findAppProcess(app, "WTF");
11336        final String processName = app == null ? "system_server"
11337                : (r == null ? "unknown" : r.processName);
11338
11339        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11340                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11341
11342        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11343
11344        return r;
11345    }
11346
11347    /**
11348     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11349     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11350     */
11351    private ProcessRecord findAppProcess(IBinder app, String reason) {
11352        if (app == null) {
11353            return null;
11354        }
11355
11356        synchronized (this) {
11357            final int NP = mProcessNames.getMap().size();
11358            for (int ip=0; ip<NP; ip++) {
11359                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11360                final int NA = apps.size();
11361                for (int ia=0; ia<NA; ia++) {
11362                    ProcessRecord p = apps.valueAt(ia);
11363                    if (p.thread != null && p.thread.asBinder() == app) {
11364                        return p;
11365                    }
11366                }
11367            }
11368
11369            Slog.w(TAG, "Can't find mystery application for " + reason
11370                    + " from pid=" + Binder.getCallingPid()
11371                    + " uid=" + Binder.getCallingUid() + ": " + app);
11372            return null;
11373        }
11374    }
11375
11376    /**
11377     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11378     * to append various headers to the dropbox log text.
11379     */
11380    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11381            StringBuilder sb) {
11382        // Watchdog thread ends up invoking this function (with
11383        // a null ProcessRecord) to add the stack file to dropbox.
11384        // Do not acquire a lock on this (am) in such cases, as it
11385        // could cause a potential deadlock, if and when watchdog
11386        // is invoked due to unavailability of lock on am and it
11387        // would prevent watchdog from killing system_server.
11388        if (process == null) {
11389            sb.append("Process: ").append(processName).append("\n");
11390            return;
11391        }
11392        // Note: ProcessRecord 'process' is guarded by the service
11393        // instance.  (notably process.pkgList, which could otherwise change
11394        // concurrently during execution of this method)
11395        synchronized (this) {
11396            sb.append("Process: ").append(processName).append("\n");
11397            int flags = process.info.flags;
11398            IPackageManager pm = AppGlobals.getPackageManager();
11399            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11400            for (int ip=0; ip<process.pkgList.size(); ip++) {
11401                String pkg = process.pkgList.keyAt(ip);
11402                sb.append("Package: ").append(pkg);
11403                try {
11404                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11405                    if (pi != null) {
11406                        sb.append(" v").append(pi.versionCode);
11407                        if (pi.versionName != null) {
11408                            sb.append(" (").append(pi.versionName).append(")");
11409                        }
11410                    }
11411                } catch (RemoteException e) {
11412                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11413                }
11414                sb.append("\n");
11415            }
11416        }
11417    }
11418
11419    private static String processClass(ProcessRecord process) {
11420        if (process == null || process.pid == MY_PID) {
11421            return "system_server";
11422        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11423            return "system_app";
11424        } else {
11425            return "data_app";
11426        }
11427    }
11428
11429    /**
11430     * Write a description of an error (crash, WTF, ANR) to the drop box.
11431     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11432     * @param process which caused the error, null means the system server
11433     * @param activity which triggered the error, null if unknown
11434     * @param parent activity related to the error, null if unknown
11435     * @param subject line related to the error, null if absent
11436     * @param report in long form describing the error, null if absent
11437     * @param logFile to include in the report, null if none
11438     * @param crashInfo giving an application stack trace, null if absent
11439     */
11440    public void addErrorToDropBox(String eventType,
11441            ProcessRecord process, String processName, ActivityRecord activity,
11442            ActivityRecord parent, String subject,
11443            final String report, final File logFile,
11444            final ApplicationErrorReport.CrashInfo crashInfo) {
11445        // NOTE -- this must never acquire the ActivityManagerService lock,
11446        // otherwise the watchdog may be prevented from resetting the system.
11447
11448        final String dropboxTag = processClass(process) + "_" + eventType;
11449        final DropBoxManager dbox = (DropBoxManager)
11450                mContext.getSystemService(Context.DROPBOX_SERVICE);
11451
11452        // Exit early if the dropbox isn't configured to accept this report type.
11453        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11454
11455        final StringBuilder sb = new StringBuilder(1024);
11456        appendDropBoxProcessHeaders(process, processName, sb);
11457        if (activity != null) {
11458            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11459        }
11460        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11461            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11462        }
11463        if (parent != null && parent != activity) {
11464            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11465        }
11466        if (subject != null) {
11467            sb.append("Subject: ").append(subject).append("\n");
11468        }
11469        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11470        if (Debug.isDebuggerConnected()) {
11471            sb.append("Debugger: Connected\n");
11472        }
11473        sb.append("\n");
11474
11475        // Do the rest in a worker thread to avoid blocking the caller on I/O
11476        // (After this point, we shouldn't access AMS internal data structures.)
11477        Thread worker = new Thread("Error dump: " + dropboxTag) {
11478            @Override
11479            public void run() {
11480                if (report != null) {
11481                    sb.append(report);
11482                }
11483                if (logFile != null) {
11484                    try {
11485                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11486                                    "\n\n[[TRUNCATED]]"));
11487                    } catch (IOException e) {
11488                        Slog.e(TAG, "Error reading " + logFile, e);
11489                    }
11490                }
11491                if (crashInfo != null && crashInfo.stackTrace != null) {
11492                    sb.append(crashInfo.stackTrace);
11493                }
11494
11495                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11496                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11497                if (lines > 0) {
11498                    sb.append("\n");
11499
11500                    // Merge several logcat streams, and take the last N lines
11501                    InputStreamReader input = null;
11502                    try {
11503                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11504                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11505                                "-b", "crash",
11506                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11507
11508                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11509                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11510                        input = new InputStreamReader(logcat.getInputStream());
11511
11512                        int num;
11513                        char[] buf = new char[8192];
11514                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11515                    } catch (IOException e) {
11516                        Slog.e(TAG, "Error running logcat", e);
11517                    } finally {
11518                        if (input != null) try { input.close(); } catch (IOException e) {}
11519                    }
11520                }
11521
11522                dbox.addText(dropboxTag, sb.toString());
11523            }
11524        };
11525
11526        if (process == null) {
11527            // If process is null, we are being called from some internal code
11528            // and may be about to die -- run this synchronously.
11529            worker.run();
11530        } else {
11531            worker.start();
11532        }
11533    }
11534
11535    /**
11536     * Bring up the "unexpected error" dialog box for a crashing app.
11537     * Deal with edge cases (intercepts from instrumented applications,
11538     * ActivityController, error intent receivers, that sort of thing).
11539     * @param r the application crashing
11540     * @param crashInfo describing the failure
11541     */
11542    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11543        long timeMillis = System.currentTimeMillis();
11544        String shortMsg = crashInfo.exceptionClassName;
11545        String longMsg = crashInfo.exceptionMessage;
11546        String stackTrace = crashInfo.stackTrace;
11547        if (shortMsg != null && longMsg != null) {
11548            longMsg = shortMsg + ": " + longMsg;
11549        } else if (shortMsg != null) {
11550            longMsg = shortMsg;
11551        }
11552
11553        AppErrorResult result = new AppErrorResult();
11554        synchronized (this) {
11555            if (mController != null) {
11556                try {
11557                    String name = r != null ? r.processName : null;
11558                    int pid = r != null ? r.pid : Binder.getCallingPid();
11559                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11560                    if (!mController.appCrashed(name, pid,
11561                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11562                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11563                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11564                            Slog.w(TAG, "Skip killing native crashed app " + name
11565                                    + "(" + pid + ") during testing");
11566                        } else {
11567                            Slog.w(TAG, "Force-killing crashed app " + name
11568                                    + " at watcher's request");
11569                            if (r != null) {
11570                                r.kill("crash", true);
11571                            } else {
11572                                // Huh.
11573                                Process.killProcess(pid);
11574                                Process.killProcessGroup(uid, pid);
11575                            }
11576                        }
11577                        return;
11578                    }
11579                } catch (RemoteException e) {
11580                    mController = null;
11581                    Watchdog.getInstance().setActivityController(null);
11582                }
11583            }
11584
11585            final long origId = Binder.clearCallingIdentity();
11586
11587            // If this process is running instrumentation, finish it.
11588            if (r != null && r.instrumentationClass != null) {
11589                Slog.w(TAG, "Error in app " + r.processName
11590                      + " running instrumentation " + r.instrumentationClass + ":");
11591                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11592                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11593                Bundle info = new Bundle();
11594                info.putString("shortMsg", shortMsg);
11595                info.putString("longMsg", longMsg);
11596                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11597                Binder.restoreCallingIdentity(origId);
11598                return;
11599            }
11600
11601            // Log crash in battery stats.
11602            if (r != null) {
11603                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
11604            }
11605
11606            // If we can't identify the process or it's already exceeded its crash quota,
11607            // quit right away without showing a crash dialog.
11608            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11609                Binder.restoreCallingIdentity(origId);
11610                return;
11611            }
11612
11613            Message msg = Message.obtain();
11614            msg.what = SHOW_ERROR_MSG;
11615            HashMap data = new HashMap();
11616            data.put("result", result);
11617            data.put("app", r);
11618            msg.obj = data;
11619            mHandler.sendMessage(msg);
11620
11621            Binder.restoreCallingIdentity(origId);
11622        }
11623
11624        int res = result.get();
11625
11626        Intent appErrorIntent = null;
11627        synchronized (this) {
11628            if (r != null && !r.isolated) {
11629                // XXX Can't keep track of crash time for isolated processes,
11630                // since they don't have a persistent identity.
11631                mProcessCrashTimes.put(r.info.processName, r.uid,
11632                        SystemClock.uptimeMillis());
11633            }
11634            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11635                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11636            }
11637        }
11638
11639        if (appErrorIntent != null) {
11640            try {
11641                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11642            } catch (ActivityNotFoundException e) {
11643                Slog.w(TAG, "bug report receiver dissappeared", e);
11644            }
11645        }
11646    }
11647
11648    Intent createAppErrorIntentLocked(ProcessRecord r,
11649            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11650        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11651        if (report == null) {
11652            return null;
11653        }
11654        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11655        result.setComponent(r.errorReportReceiver);
11656        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11657        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11658        return result;
11659    }
11660
11661    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11662            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11663        if (r.errorReportReceiver == null) {
11664            return null;
11665        }
11666
11667        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11668            return null;
11669        }
11670
11671        ApplicationErrorReport report = new ApplicationErrorReport();
11672        report.packageName = r.info.packageName;
11673        report.installerPackageName = r.errorReportReceiver.getPackageName();
11674        report.processName = r.processName;
11675        report.time = timeMillis;
11676        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11677
11678        if (r.crashing || r.forceCrashReport) {
11679            report.type = ApplicationErrorReport.TYPE_CRASH;
11680            report.crashInfo = crashInfo;
11681        } else if (r.notResponding) {
11682            report.type = ApplicationErrorReport.TYPE_ANR;
11683            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11684
11685            report.anrInfo.activity = r.notRespondingReport.tag;
11686            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11687            report.anrInfo.info = r.notRespondingReport.longMsg;
11688        }
11689
11690        return report;
11691    }
11692
11693    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11694        enforceNotIsolatedCaller("getProcessesInErrorState");
11695        // assume our apps are happy - lazy create the list
11696        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11697
11698        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11699                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11700        int userId = UserHandle.getUserId(Binder.getCallingUid());
11701
11702        synchronized (this) {
11703
11704            // iterate across all processes
11705            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11706                ProcessRecord app = mLruProcesses.get(i);
11707                if (!allUsers && app.userId != userId) {
11708                    continue;
11709                }
11710                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11711                    // This one's in trouble, so we'll generate a report for it
11712                    // crashes are higher priority (in case there's a crash *and* an anr)
11713                    ActivityManager.ProcessErrorStateInfo report = null;
11714                    if (app.crashing) {
11715                        report = app.crashingReport;
11716                    } else if (app.notResponding) {
11717                        report = app.notRespondingReport;
11718                    }
11719
11720                    if (report != null) {
11721                        if (errList == null) {
11722                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11723                        }
11724                        errList.add(report);
11725                    } else {
11726                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11727                                " crashing = " + app.crashing +
11728                                " notResponding = " + app.notResponding);
11729                    }
11730                }
11731            }
11732        }
11733
11734        return errList;
11735    }
11736
11737    static int procStateToImportance(int procState, int memAdj,
11738            ActivityManager.RunningAppProcessInfo currApp) {
11739        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11740        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11741            currApp.lru = memAdj;
11742        } else {
11743            currApp.lru = 0;
11744        }
11745        return imp;
11746    }
11747
11748    private void fillInProcMemInfo(ProcessRecord app,
11749            ActivityManager.RunningAppProcessInfo outInfo) {
11750        outInfo.pid = app.pid;
11751        outInfo.uid = app.info.uid;
11752        if (mHeavyWeightProcess == app) {
11753            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11754        }
11755        if (app.persistent) {
11756            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11757        }
11758        if (app.activities.size() > 0) {
11759            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11760        }
11761        outInfo.lastTrimLevel = app.trimMemoryLevel;
11762        int adj = app.curAdj;
11763        int procState = app.curProcState;
11764        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11765        outInfo.importanceReasonCode = app.adjTypeCode;
11766        outInfo.processState = app.curProcState;
11767    }
11768
11769    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11770        enforceNotIsolatedCaller("getRunningAppProcesses");
11771        // Lazy instantiation of list
11772        List<ActivityManager.RunningAppProcessInfo> runList = null;
11773        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11774                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11775        int userId = UserHandle.getUserId(Binder.getCallingUid());
11776        synchronized (this) {
11777            // Iterate across all processes
11778            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11779                ProcessRecord app = mLruProcesses.get(i);
11780                if (!allUsers && app.userId != userId) {
11781                    continue;
11782                }
11783                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11784                    // Generate process state info for running application
11785                    ActivityManager.RunningAppProcessInfo currApp =
11786                        new ActivityManager.RunningAppProcessInfo(app.processName,
11787                                app.pid, app.getPackageList());
11788                    fillInProcMemInfo(app, currApp);
11789                    if (app.adjSource instanceof ProcessRecord) {
11790                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11791                        currApp.importanceReasonImportance =
11792                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11793                                        app.adjSourceProcState);
11794                    } else if (app.adjSource instanceof ActivityRecord) {
11795                        ActivityRecord r = (ActivityRecord)app.adjSource;
11796                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11797                    }
11798                    if (app.adjTarget instanceof ComponentName) {
11799                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11800                    }
11801                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11802                    //        + " lru=" + currApp.lru);
11803                    if (runList == null) {
11804                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11805                    }
11806                    runList.add(currApp);
11807                }
11808            }
11809        }
11810        return runList;
11811    }
11812
11813    public List<ApplicationInfo> getRunningExternalApplications() {
11814        enforceNotIsolatedCaller("getRunningExternalApplications");
11815        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11816        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11817        if (runningApps != null && runningApps.size() > 0) {
11818            Set<String> extList = new HashSet<String>();
11819            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11820                if (app.pkgList != null) {
11821                    for (String pkg : app.pkgList) {
11822                        extList.add(pkg);
11823                    }
11824                }
11825            }
11826            IPackageManager pm = AppGlobals.getPackageManager();
11827            for (String pkg : extList) {
11828                try {
11829                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11830                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11831                        retList.add(info);
11832                    }
11833                } catch (RemoteException e) {
11834                }
11835            }
11836        }
11837        return retList;
11838    }
11839
11840    @Override
11841    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11842        enforceNotIsolatedCaller("getMyMemoryState");
11843        synchronized (this) {
11844            ProcessRecord proc;
11845            synchronized (mPidsSelfLocked) {
11846                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11847            }
11848            fillInProcMemInfo(proc, outInfo);
11849        }
11850    }
11851
11852    @Override
11853    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11854        if (checkCallingPermission(android.Manifest.permission.DUMP)
11855                != PackageManager.PERMISSION_GRANTED) {
11856            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11857                    + Binder.getCallingPid()
11858                    + ", uid=" + Binder.getCallingUid()
11859                    + " without permission "
11860                    + android.Manifest.permission.DUMP);
11861            return;
11862        }
11863
11864        boolean dumpAll = false;
11865        boolean dumpClient = false;
11866        String dumpPackage = null;
11867
11868        int opti = 0;
11869        while (opti < args.length) {
11870            String opt = args[opti];
11871            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11872                break;
11873            }
11874            opti++;
11875            if ("-a".equals(opt)) {
11876                dumpAll = true;
11877            } else if ("-c".equals(opt)) {
11878                dumpClient = true;
11879            } else if ("-p".equals(opt)) {
11880                if (opti < args.length) {
11881                    dumpPackage = args[opti];
11882                    opti++;
11883                } else {
11884                    pw.println("Error: -p option requires package argument");
11885                    return;
11886                }
11887                dumpClient = true;
11888            } else if ("-h".equals(opt)) {
11889                pw.println("Activity manager dump options:");
11890                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
11891                pw.println("  cmd may be one of:");
11892                pw.println("    a[ctivities]: activity stack state");
11893                pw.println("    r[recents]: recent activities state");
11894                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11895                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11896                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11897                pw.println("    o[om]: out of memory management");
11898                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11899                pw.println("    provider [COMP_SPEC]: provider client-side state");
11900                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11901                pw.println("    as[sociations]: tracked app associations");
11902                pw.println("    service [COMP_SPEC]: service client-side state");
11903                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11904                pw.println("    all: dump all activities");
11905                pw.println("    top: dump the top activity");
11906                pw.println("    write: write all pending state to storage");
11907                pw.println("    track-associations: enable association tracking");
11908                pw.println("    untrack-associations: disable and clear association tracking");
11909                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11910                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11911                pw.println("    a partial substring in a component name, a");
11912                pw.println("    hex object identifier.");
11913                pw.println("  -a: include all available server state.");
11914                pw.println("  -c: include client state.");
11915                pw.println("  -p: limit output to given package.");
11916                return;
11917            } else {
11918                pw.println("Unknown argument: " + opt + "; use -h for help");
11919            }
11920        }
11921
11922        long origId = Binder.clearCallingIdentity();
11923        boolean more = false;
11924        // Is the caller requesting to dump a particular piece of data?
11925        if (opti < args.length) {
11926            String cmd = args[opti];
11927            opti++;
11928            if ("activities".equals(cmd) || "a".equals(cmd)) {
11929                synchronized (this) {
11930                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
11931                }
11932            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
11933                synchronized (this) {
11934                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
11935                }
11936            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11937                String[] newArgs;
11938                String name;
11939                if (opti >= args.length) {
11940                    name = null;
11941                    newArgs = EMPTY_STRING_ARRAY;
11942                } else {
11943                    dumpPackage = args[opti];
11944                    opti++;
11945                    newArgs = new String[args.length - opti];
11946                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11947                            args.length - opti);
11948                }
11949                synchronized (this) {
11950                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
11951                }
11952            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11953                String[] newArgs;
11954                String name;
11955                if (opti >= args.length) {
11956                    name = null;
11957                    newArgs = EMPTY_STRING_ARRAY;
11958                } else {
11959                    dumpPackage = args[opti];
11960                    opti++;
11961                    newArgs = new String[args.length - opti];
11962                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11963                            args.length - opti);
11964                }
11965                synchronized (this) {
11966                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
11967                }
11968            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11969                String[] newArgs;
11970                String name;
11971                if (opti >= args.length) {
11972                    name = null;
11973                    newArgs = EMPTY_STRING_ARRAY;
11974                } else {
11975                    dumpPackage = args[opti];
11976                    opti++;
11977                    newArgs = new String[args.length - opti];
11978                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11979                            args.length - opti);
11980                }
11981                synchronized (this) {
11982                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
11983                }
11984            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11985                synchronized (this) {
11986                    dumpOomLocked(fd, pw, args, opti, true);
11987                }
11988            } else if ("provider".equals(cmd)) {
11989                String[] newArgs;
11990                String name;
11991                if (opti >= args.length) {
11992                    name = null;
11993                    newArgs = EMPTY_STRING_ARRAY;
11994                } else {
11995                    name = args[opti];
11996                    opti++;
11997                    newArgs = new String[args.length - opti];
11998                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11999                }
12000                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12001                    pw.println("No providers match: " + name);
12002                    pw.println("Use -h for help.");
12003                }
12004            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12005                synchronized (this) {
12006                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12007                }
12008            } else if ("service".equals(cmd)) {
12009                String[] newArgs;
12010                String name;
12011                if (opti >= args.length) {
12012                    name = null;
12013                    newArgs = EMPTY_STRING_ARRAY;
12014                } else {
12015                    name = args[opti];
12016                    opti++;
12017                    newArgs = new String[args.length - opti];
12018                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12019                            args.length - opti);
12020                }
12021                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12022                    pw.println("No services match: " + name);
12023                    pw.println("Use -h for help.");
12024                }
12025            } else if ("package".equals(cmd)) {
12026                String[] newArgs;
12027                if (opti >= args.length) {
12028                    pw.println("package: no package name specified");
12029                    pw.println("Use -h for help.");
12030                } else {
12031                    dumpPackage = args[opti];
12032                    opti++;
12033                    newArgs = new String[args.length - opti];
12034                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12035                            args.length - opti);
12036                    args = newArgs;
12037                    opti = 0;
12038                    more = true;
12039                }
12040            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12041                synchronized (this) {
12042                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12043                }
12044            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12045                synchronized (this) {
12046                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12047                }
12048            } else if ("write".equals(cmd)) {
12049                mTaskPersister.flush();
12050                pw.println("All tasks persisted.");
12051                return;
12052            } else if ("track-associations".equals(cmd)) {
12053                synchronized (this) {
12054                    if (!mTrackingAssociations) {
12055                        mTrackingAssociations = true;
12056                        pw.println("Association tracking started.");
12057                    } else {
12058                        pw.println("Association tracking already enabled.");
12059                    }
12060                }
12061                return;
12062            } else if ("untrack-associations".equals(cmd)) {
12063                synchronized (this) {
12064                    if (mTrackingAssociations) {
12065                        mTrackingAssociations = false;
12066                        mAssociations.clear();
12067                        pw.println("Association tracking stopped.");
12068                    } else {
12069                        pw.println("Association tracking not running.");
12070                    }
12071                }
12072                return;
12073            } else {
12074                // Dumping a single activity?
12075                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12076                    pw.println("Bad activity command, or no activities match: " + cmd);
12077                    pw.println("Use -h for help.");
12078                }
12079            }
12080            if (!more) {
12081                Binder.restoreCallingIdentity(origId);
12082                return;
12083            }
12084        }
12085
12086        // No piece of data specified, dump everything.
12087        synchronized (this) {
12088            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12089            pw.println();
12090            if (dumpAll) {
12091                pw.println("-------------------------------------------------------------------------------");
12092            }
12093            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12094            pw.println();
12095            if (dumpAll) {
12096                pw.println("-------------------------------------------------------------------------------");
12097            }
12098            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12099            pw.println();
12100            if (dumpAll) {
12101                pw.println("-------------------------------------------------------------------------------");
12102            }
12103            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12104            pw.println();
12105            if (dumpAll) {
12106                pw.println("-------------------------------------------------------------------------------");
12107            }
12108            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12109            pw.println();
12110            if (dumpAll) {
12111                pw.println("-------------------------------------------------------------------------------");
12112            }
12113            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12114            if (mAssociations.size() > 0) {
12115                pw.println();
12116                if (dumpAll) {
12117                    pw.println("-------------------------------------------------------------------------------");
12118                }
12119                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12120            }
12121            pw.println();
12122            if (dumpAll) {
12123                pw.println("-------------------------------------------------------------------------------");
12124            }
12125            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12126        }
12127        Binder.restoreCallingIdentity(origId);
12128    }
12129
12130    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12131            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12132        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12133
12134        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12135                dumpPackage);
12136        boolean needSep = printedAnything;
12137
12138        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12139                dumpPackage, needSep, "  mFocusedActivity: ");
12140        if (printed) {
12141            printedAnything = true;
12142            needSep = false;
12143        }
12144
12145        if (dumpPackage == null) {
12146            if (needSep) {
12147                pw.println();
12148            }
12149            needSep = true;
12150            printedAnything = true;
12151            mStackSupervisor.dump(pw, "  ");
12152        }
12153
12154        if (!printedAnything) {
12155            pw.println("  (nothing)");
12156        }
12157    }
12158
12159    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12160            int opti, boolean dumpAll, String dumpPackage) {
12161        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12162
12163        boolean printedAnything = false;
12164
12165        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12166            boolean printedHeader = false;
12167
12168            final int N = mRecentTasks.size();
12169            for (int i=0; i<N; i++) {
12170                TaskRecord tr = mRecentTasks.get(i);
12171                if (dumpPackage != null) {
12172                    if (tr.realActivity == null ||
12173                            !dumpPackage.equals(tr.realActivity)) {
12174                        continue;
12175                    }
12176                }
12177                if (!printedHeader) {
12178                    pw.println("  Recent tasks:");
12179                    printedHeader = true;
12180                    printedAnything = true;
12181                }
12182                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12183                        pw.println(tr);
12184                if (dumpAll) {
12185                    mRecentTasks.get(i).dump(pw, "    ");
12186                }
12187            }
12188        }
12189
12190        if (!printedAnything) {
12191            pw.println("  (nothing)");
12192        }
12193    }
12194
12195    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12196            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12197        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12198
12199        int dumpUid = 0;
12200        if (dumpPackage != null) {
12201            IPackageManager pm = AppGlobals.getPackageManager();
12202            try {
12203                dumpUid = pm.getPackageUid(dumpPackage, 0);
12204            } catch (RemoteException e) {
12205            }
12206        }
12207
12208        boolean printedAnything = false;
12209
12210        final long now = SystemClock.uptimeMillis();
12211
12212        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12213            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12214                    = mAssociations.valueAt(i1);
12215            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12216                SparseArray<ArrayMap<String, Association>> sourceUids
12217                        = targetComponents.valueAt(i2);
12218                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12219                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12220                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12221                        Association ass = sourceProcesses.valueAt(i4);
12222                        if (dumpPackage != null) {
12223                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12224                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12225                                continue;
12226                            }
12227                        }
12228                        printedAnything = true;
12229                        pw.print("  ");
12230                        pw.print(ass.mTargetProcess);
12231                        pw.print("/");
12232                        UserHandle.formatUid(pw, ass.mTargetUid);
12233                        pw.print(" <- ");
12234                        pw.print(ass.mSourceProcess);
12235                        pw.print("/");
12236                        UserHandle.formatUid(pw, ass.mSourceUid);
12237                        pw.println();
12238                        pw.print("    via ");
12239                        pw.print(ass.mTargetComponent.flattenToShortString());
12240                        pw.println();
12241                        pw.print("    ");
12242                        long dur = ass.mTime;
12243                        if (ass.mNesting > 0) {
12244                            dur += now - ass.mStartTime;
12245                        }
12246                        TimeUtils.formatDuration(dur, pw);
12247                        pw.print(" (");
12248                        pw.print(ass.mCount);
12249                        pw.println(" times)");
12250                        if (ass.mNesting > 0) {
12251                            pw.print("    ");
12252                            pw.print(" Currently active: ");
12253                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
12254                            pw.println();
12255                        }
12256                    }
12257                }
12258            }
12259
12260        }
12261
12262        if (!printedAnything) {
12263            pw.println("  (nothing)");
12264        }
12265    }
12266
12267    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12268            int opti, boolean dumpAll, String dumpPackage) {
12269        boolean needSep = false;
12270        boolean printedAnything = false;
12271        int numPers = 0;
12272
12273        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12274
12275        if (dumpAll) {
12276            final int NP = mProcessNames.getMap().size();
12277            for (int ip=0; ip<NP; ip++) {
12278                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12279                final int NA = procs.size();
12280                for (int ia=0; ia<NA; ia++) {
12281                    ProcessRecord r = procs.valueAt(ia);
12282                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12283                        continue;
12284                    }
12285                    if (!needSep) {
12286                        pw.println("  All known processes:");
12287                        needSep = true;
12288                        printedAnything = true;
12289                    }
12290                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12291                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12292                        pw.print(" "); pw.println(r);
12293                    r.dump(pw, "    ");
12294                    if (r.persistent) {
12295                        numPers++;
12296                    }
12297                }
12298            }
12299        }
12300
12301        if (mIsolatedProcesses.size() > 0) {
12302            boolean printed = false;
12303            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12304                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12305                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12306                    continue;
12307                }
12308                if (!printed) {
12309                    if (needSep) {
12310                        pw.println();
12311                    }
12312                    pw.println("  Isolated process list (sorted by uid):");
12313                    printedAnything = true;
12314                    printed = true;
12315                    needSep = true;
12316                }
12317                pw.println(String.format("%sIsolated #%2d: %s",
12318                        "    ", i, r.toString()));
12319            }
12320        }
12321
12322        if (mLruProcesses.size() > 0) {
12323            if (needSep) {
12324                pw.println();
12325            }
12326            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12327                    pw.print(" total, non-act at ");
12328                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12329                    pw.print(", non-svc at ");
12330                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12331                    pw.println("):");
12332            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12333            needSep = true;
12334            printedAnything = true;
12335        }
12336
12337        if (dumpAll || dumpPackage != null) {
12338            synchronized (mPidsSelfLocked) {
12339                boolean printed = false;
12340                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12341                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12342                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12343                        continue;
12344                    }
12345                    if (!printed) {
12346                        if (needSep) pw.println();
12347                        needSep = true;
12348                        pw.println("  PID mappings:");
12349                        printed = true;
12350                        printedAnything = true;
12351                    }
12352                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12353                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12354                }
12355            }
12356        }
12357
12358        if (mForegroundProcesses.size() > 0) {
12359            synchronized (mPidsSelfLocked) {
12360                boolean printed = false;
12361                for (int i=0; i<mForegroundProcesses.size(); i++) {
12362                    ProcessRecord r = mPidsSelfLocked.get(
12363                            mForegroundProcesses.valueAt(i).pid);
12364                    if (dumpPackage != null && (r == null
12365                            || !r.pkgList.containsKey(dumpPackage))) {
12366                        continue;
12367                    }
12368                    if (!printed) {
12369                        if (needSep) pw.println();
12370                        needSep = true;
12371                        pw.println("  Foreground Processes:");
12372                        printed = true;
12373                        printedAnything = true;
12374                    }
12375                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12376                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12377                }
12378            }
12379        }
12380
12381        if (mPersistentStartingProcesses.size() > 0) {
12382            if (needSep) pw.println();
12383            needSep = true;
12384            printedAnything = true;
12385            pw.println("  Persisent processes that are starting:");
12386            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12387                    "Starting Norm", "Restarting PERS", dumpPackage);
12388        }
12389
12390        if (mRemovedProcesses.size() > 0) {
12391            if (needSep) pw.println();
12392            needSep = true;
12393            printedAnything = true;
12394            pw.println("  Processes that are being removed:");
12395            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12396                    "Removed Norm", "Removed PERS", dumpPackage);
12397        }
12398
12399        if (mProcessesOnHold.size() > 0) {
12400            if (needSep) pw.println();
12401            needSep = true;
12402            printedAnything = true;
12403            pw.println("  Processes that are on old until the system is ready:");
12404            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12405                    "OnHold Norm", "OnHold PERS", dumpPackage);
12406        }
12407
12408        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12409
12410        if (mProcessCrashTimes.getMap().size() > 0) {
12411            boolean printed = false;
12412            long now = SystemClock.uptimeMillis();
12413            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12414            final int NP = pmap.size();
12415            for (int ip=0; ip<NP; ip++) {
12416                String pname = pmap.keyAt(ip);
12417                SparseArray<Long> uids = pmap.valueAt(ip);
12418                final int N = uids.size();
12419                for (int i=0; i<N; i++) {
12420                    int puid = uids.keyAt(i);
12421                    ProcessRecord r = mProcessNames.get(pname, puid);
12422                    if (dumpPackage != null && (r == null
12423                            || !r.pkgList.containsKey(dumpPackage))) {
12424                        continue;
12425                    }
12426                    if (!printed) {
12427                        if (needSep) pw.println();
12428                        needSep = true;
12429                        pw.println("  Time since processes crashed:");
12430                        printed = true;
12431                        printedAnything = true;
12432                    }
12433                    pw.print("    Process "); pw.print(pname);
12434                            pw.print(" uid "); pw.print(puid);
12435                            pw.print(": last crashed ");
12436                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12437                            pw.println(" ago");
12438                }
12439            }
12440        }
12441
12442        if (mBadProcesses.getMap().size() > 0) {
12443            boolean printed = false;
12444            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12445            final int NP = pmap.size();
12446            for (int ip=0; ip<NP; ip++) {
12447                String pname = pmap.keyAt(ip);
12448                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12449                final int N = uids.size();
12450                for (int i=0; i<N; i++) {
12451                    int puid = uids.keyAt(i);
12452                    ProcessRecord r = mProcessNames.get(pname, puid);
12453                    if (dumpPackage != null && (r == null
12454                            || !r.pkgList.containsKey(dumpPackage))) {
12455                        continue;
12456                    }
12457                    if (!printed) {
12458                        if (needSep) pw.println();
12459                        needSep = true;
12460                        pw.println("  Bad processes:");
12461                        printedAnything = true;
12462                    }
12463                    BadProcessInfo info = uids.valueAt(i);
12464                    pw.print("    Bad process "); pw.print(pname);
12465                            pw.print(" uid "); pw.print(puid);
12466                            pw.print(": crashed at time "); pw.println(info.time);
12467                    if (info.shortMsg != null) {
12468                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12469                    }
12470                    if (info.longMsg != null) {
12471                        pw.print("      Long msg: "); pw.println(info.longMsg);
12472                    }
12473                    if (info.stack != null) {
12474                        pw.println("      Stack:");
12475                        int lastPos = 0;
12476                        for (int pos=0; pos<info.stack.length(); pos++) {
12477                            if (info.stack.charAt(pos) == '\n') {
12478                                pw.print("        ");
12479                                pw.write(info.stack, lastPos, pos-lastPos);
12480                                pw.println();
12481                                lastPos = pos+1;
12482                            }
12483                        }
12484                        if (lastPos < info.stack.length()) {
12485                            pw.print("        ");
12486                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12487                            pw.println();
12488                        }
12489                    }
12490                }
12491            }
12492        }
12493
12494        if (dumpPackage == null) {
12495            pw.println();
12496            needSep = false;
12497            pw.println("  mStartedUsers:");
12498            for (int i=0; i<mStartedUsers.size(); i++) {
12499                UserStartedState uss = mStartedUsers.valueAt(i);
12500                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12501                        pw.print(": "); uss.dump("", pw);
12502            }
12503            pw.print("  mStartedUserArray: [");
12504            for (int i=0; i<mStartedUserArray.length; i++) {
12505                if (i > 0) pw.print(", ");
12506                pw.print(mStartedUserArray[i]);
12507            }
12508            pw.println("]");
12509            pw.print("  mUserLru: [");
12510            for (int i=0; i<mUserLru.size(); i++) {
12511                if (i > 0) pw.print(", ");
12512                pw.print(mUserLru.get(i));
12513            }
12514            pw.println("]");
12515            if (dumpAll) {
12516                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12517            }
12518            synchronized (mUserProfileGroupIdsSelfLocked) {
12519                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12520                    pw.println("  mUserProfileGroupIds:");
12521                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12522                        pw.print("    User #");
12523                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12524                        pw.print(" -> profile #");
12525                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12526                    }
12527                }
12528            }
12529        }
12530        if (mHomeProcess != null && (dumpPackage == null
12531                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12532            if (needSep) {
12533                pw.println();
12534                needSep = false;
12535            }
12536            pw.println("  mHomeProcess: " + mHomeProcess);
12537        }
12538        if (mPreviousProcess != null && (dumpPackage == null
12539                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12540            if (needSep) {
12541                pw.println();
12542                needSep = false;
12543            }
12544            pw.println("  mPreviousProcess: " + mPreviousProcess);
12545        }
12546        if (dumpAll) {
12547            StringBuilder sb = new StringBuilder(128);
12548            sb.append("  mPreviousProcessVisibleTime: ");
12549            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12550            pw.println(sb);
12551        }
12552        if (mHeavyWeightProcess != null && (dumpPackage == null
12553                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12554            if (needSep) {
12555                pw.println();
12556                needSep = false;
12557            }
12558            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12559        }
12560        if (dumpPackage == null) {
12561            pw.println("  mConfiguration: " + mConfiguration);
12562        }
12563        if (dumpAll) {
12564            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12565            if (mCompatModePackages.getPackages().size() > 0) {
12566                boolean printed = false;
12567                for (Map.Entry<String, Integer> entry
12568                        : mCompatModePackages.getPackages().entrySet()) {
12569                    String pkg = entry.getKey();
12570                    int mode = entry.getValue();
12571                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12572                        continue;
12573                    }
12574                    if (!printed) {
12575                        pw.println("  mScreenCompatPackages:");
12576                        printed = true;
12577                    }
12578                    pw.print("    "); pw.print(pkg); pw.print(": ");
12579                            pw.print(mode); pw.println();
12580                }
12581            }
12582        }
12583        if (dumpPackage == null) {
12584            pw.println("  mWakefulness="
12585                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12586            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12587                    + lockScreenShownToString());
12588            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
12589                    + " mTestPssMode=" + mTestPssMode);
12590        }
12591        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12592                || mOrigWaitForDebugger) {
12593            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12594                    || dumpPackage.equals(mOrigDebugApp)) {
12595                if (needSep) {
12596                    pw.println();
12597                    needSep = false;
12598                }
12599                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12600                        + " mDebugTransient=" + mDebugTransient
12601                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12602            }
12603        }
12604        if (mOpenGlTraceApp != null) {
12605            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12606                if (needSep) {
12607                    pw.println();
12608                    needSep = false;
12609                }
12610                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12611            }
12612        }
12613        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12614                || mProfileFd != null) {
12615            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12616                if (needSep) {
12617                    pw.println();
12618                    needSep = false;
12619                }
12620                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12621                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12622                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12623                        + mAutoStopProfiler);
12624                pw.println("  mProfileType=" + mProfileType);
12625            }
12626        }
12627        if (dumpPackage == null) {
12628            if (mAlwaysFinishActivities || mController != null) {
12629                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12630                        + " mController=" + mController);
12631            }
12632            if (dumpAll) {
12633                pw.println("  Total persistent processes: " + numPers);
12634                pw.println("  mProcessesReady=" + mProcessesReady
12635                        + " mSystemReady=" + mSystemReady
12636                        + " mBooted=" + mBooted
12637                        + " mFactoryTest=" + mFactoryTest);
12638                pw.println("  mBooting=" + mBooting
12639                        + " mCallFinishBooting=" + mCallFinishBooting
12640                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12641                pw.print("  mLastPowerCheckRealtime=");
12642                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12643                        pw.println("");
12644                pw.print("  mLastPowerCheckUptime=");
12645                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12646                        pw.println("");
12647                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12648                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12649                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12650                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12651                        + " (" + mLruProcesses.size() + " total)"
12652                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12653                        + " mNumServiceProcs=" + mNumServiceProcs
12654                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12655                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12656                        + " mLastMemoryLevel" + mLastMemoryLevel
12657                        + " mLastNumProcesses" + mLastNumProcesses);
12658                long now = SystemClock.uptimeMillis();
12659                pw.print("  mLastIdleTime=");
12660                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12661                        pw.print(" mLowRamSinceLastIdle=");
12662                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12663                        pw.println();
12664            }
12665        }
12666
12667        if (!printedAnything) {
12668            pw.println("  (nothing)");
12669        }
12670    }
12671
12672    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12673            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12674        if (mProcessesToGc.size() > 0) {
12675            boolean printed = false;
12676            long now = SystemClock.uptimeMillis();
12677            for (int i=0; i<mProcessesToGc.size(); i++) {
12678                ProcessRecord proc = mProcessesToGc.get(i);
12679                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12680                    continue;
12681                }
12682                if (!printed) {
12683                    if (needSep) pw.println();
12684                    needSep = true;
12685                    pw.println("  Processes that are waiting to GC:");
12686                    printed = true;
12687                }
12688                pw.print("    Process "); pw.println(proc);
12689                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12690                        pw.print(", last gced=");
12691                        pw.print(now-proc.lastRequestedGc);
12692                        pw.print(" ms ago, last lowMem=");
12693                        pw.print(now-proc.lastLowMemory);
12694                        pw.println(" ms ago");
12695
12696            }
12697        }
12698        return needSep;
12699    }
12700
12701    void printOomLevel(PrintWriter pw, String name, int adj) {
12702        pw.print("    ");
12703        if (adj >= 0) {
12704            pw.print(' ');
12705            if (adj < 10) pw.print(' ');
12706        } else {
12707            if (adj > -10) pw.print(' ');
12708        }
12709        pw.print(adj);
12710        pw.print(": ");
12711        pw.print(name);
12712        pw.print(" (");
12713        pw.print(mProcessList.getMemLevel(adj)/1024);
12714        pw.println(" kB)");
12715    }
12716
12717    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12718            int opti, boolean dumpAll) {
12719        boolean needSep = false;
12720
12721        if (mLruProcesses.size() > 0) {
12722            if (needSep) pw.println();
12723            needSep = true;
12724            pw.println("  OOM levels:");
12725            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12726            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12727            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12728            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12729            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12730            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12731            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12732            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12733            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12734            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12735            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12736            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12737            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12738            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12739
12740            if (needSep) pw.println();
12741            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12742                    pw.print(" total, non-act at ");
12743                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12744                    pw.print(", non-svc at ");
12745                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12746                    pw.println("):");
12747            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12748            needSep = true;
12749        }
12750
12751        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12752
12753        pw.println();
12754        pw.println("  mHomeProcess: " + mHomeProcess);
12755        pw.println("  mPreviousProcess: " + mPreviousProcess);
12756        if (mHeavyWeightProcess != null) {
12757            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12758        }
12759
12760        return true;
12761    }
12762
12763    /**
12764     * There are three ways to call this:
12765     *  - no provider specified: dump all the providers
12766     *  - a flattened component name that matched an existing provider was specified as the
12767     *    first arg: dump that one provider
12768     *  - the first arg isn't the flattened component name of an existing provider:
12769     *    dump all providers whose component contains the first arg as a substring
12770     */
12771    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12772            int opti, boolean dumpAll) {
12773        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12774    }
12775
12776    static class ItemMatcher {
12777        ArrayList<ComponentName> components;
12778        ArrayList<String> strings;
12779        ArrayList<Integer> objects;
12780        boolean all;
12781
12782        ItemMatcher() {
12783            all = true;
12784        }
12785
12786        void build(String name) {
12787            ComponentName componentName = ComponentName.unflattenFromString(name);
12788            if (componentName != null) {
12789                if (components == null) {
12790                    components = new ArrayList<ComponentName>();
12791                }
12792                components.add(componentName);
12793                all = false;
12794            } else {
12795                int objectId = 0;
12796                // Not a '/' separated full component name; maybe an object ID?
12797                try {
12798                    objectId = Integer.parseInt(name, 16);
12799                    if (objects == null) {
12800                        objects = new ArrayList<Integer>();
12801                    }
12802                    objects.add(objectId);
12803                    all = false;
12804                } catch (RuntimeException e) {
12805                    // Not an integer; just do string match.
12806                    if (strings == null) {
12807                        strings = new ArrayList<String>();
12808                    }
12809                    strings.add(name);
12810                    all = false;
12811                }
12812            }
12813        }
12814
12815        int build(String[] args, int opti) {
12816            for (; opti<args.length; opti++) {
12817                String name = args[opti];
12818                if ("--".equals(name)) {
12819                    return opti+1;
12820                }
12821                build(name);
12822            }
12823            return opti;
12824        }
12825
12826        boolean match(Object object, ComponentName comp) {
12827            if (all) {
12828                return true;
12829            }
12830            if (components != null) {
12831                for (int i=0; i<components.size(); i++) {
12832                    if (components.get(i).equals(comp)) {
12833                        return true;
12834                    }
12835                }
12836            }
12837            if (objects != null) {
12838                for (int i=0; i<objects.size(); i++) {
12839                    if (System.identityHashCode(object) == objects.get(i)) {
12840                        return true;
12841                    }
12842                }
12843            }
12844            if (strings != null) {
12845                String flat = comp.flattenToString();
12846                for (int i=0; i<strings.size(); i++) {
12847                    if (flat.contains(strings.get(i))) {
12848                        return true;
12849                    }
12850                }
12851            }
12852            return false;
12853        }
12854    }
12855
12856    /**
12857     * There are three things that cmd can be:
12858     *  - a flattened component name that matches an existing activity
12859     *  - the cmd arg isn't the flattened component name of an existing activity:
12860     *    dump all activity whose component contains the cmd as a substring
12861     *  - A hex number of the ActivityRecord object instance.
12862     */
12863    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12864            int opti, boolean dumpAll) {
12865        ArrayList<ActivityRecord> activities;
12866
12867        synchronized (this) {
12868            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12869        }
12870
12871        if (activities.size() <= 0) {
12872            return false;
12873        }
12874
12875        String[] newArgs = new String[args.length - opti];
12876        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12877
12878        TaskRecord lastTask = null;
12879        boolean needSep = false;
12880        for (int i=activities.size()-1; i>=0; i--) {
12881            ActivityRecord r = activities.get(i);
12882            if (needSep) {
12883                pw.println();
12884            }
12885            needSep = true;
12886            synchronized (this) {
12887                if (lastTask != r.task) {
12888                    lastTask = r.task;
12889                    pw.print("TASK "); pw.print(lastTask.affinity);
12890                            pw.print(" id="); pw.println(lastTask.taskId);
12891                    if (dumpAll) {
12892                        lastTask.dump(pw, "  ");
12893                    }
12894                }
12895            }
12896            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12897        }
12898        return true;
12899    }
12900
12901    /**
12902     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12903     * there is a thread associated with the activity.
12904     */
12905    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12906            final ActivityRecord r, String[] args, boolean dumpAll) {
12907        String innerPrefix = prefix + "  ";
12908        synchronized (this) {
12909            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12910                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12911                    pw.print(" pid=");
12912                    if (r.app != null) pw.println(r.app.pid);
12913                    else pw.println("(not running)");
12914            if (dumpAll) {
12915                r.dump(pw, innerPrefix);
12916            }
12917        }
12918        if (r.app != null && r.app.thread != null) {
12919            // flush anything that is already in the PrintWriter since the thread is going
12920            // to write to the file descriptor directly
12921            pw.flush();
12922            try {
12923                TransferPipe tp = new TransferPipe();
12924                try {
12925                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12926                            r.appToken, innerPrefix, args);
12927                    tp.go(fd);
12928                } finally {
12929                    tp.kill();
12930                }
12931            } catch (IOException e) {
12932                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12933            } catch (RemoteException e) {
12934                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12935            }
12936        }
12937    }
12938
12939    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12940            int opti, boolean dumpAll, String dumpPackage) {
12941        boolean needSep = false;
12942        boolean onlyHistory = false;
12943        boolean printedAnything = false;
12944
12945        if ("history".equals(dumpPackage)) {
12946            if (opti < args.length && "-s".equals(args[opti])) {
12947                dumpAll = false;
12948            }
12949            onlyHistory = true;
12950            dumpPackage = null;
12951        }
12952
12953        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12954        if (!onlyHistory && dumpAll) {
12955            if (mRegisteredReceivers.size() > 0) {
12956                boolean printed = false;
12957                Iterator it = mRegisteredReceivers.values().iterator();
12958                while (it.hasNext()) {
12959                    ReceiverList r = (ReceiverList)it.next();
12960                    if (dumpPackage != null && (r.app == null ||
12961                            !dumpPackage.equals(r.app.info.packageName))) {
12962                        continue;
12963                    }
12964                    if (!printed) {
12965                        pw.println("  Registered Receivers:");
12966                        needSep = true;
12967                        printed = true;
12968                        printedAnything = true;
12969                    }
12970                    pw.print("  * "); pw.println(r);
12971                    r.dump(pw, "    ");
12972                }
12973            }
12974
12975            if (mReceiverResolver.dump(pw, needSep ?
12976                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12977                    "    ", dumpPackage, false, false)) {
12978                needSep = true;
12979                printedAnything = true;
12980            }
12981        }
12982
12983        for (BroadcastQueue q : mBroadcastQueues) {
12984            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12985            printedAnything |= needSep;
12986        }
12987
12988        needSep = true;
12989
12990        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12991            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12992                if (needSep) {
12993                    pw.println();
12994                }
12995                needSep = true;
12996                printedAnything = true;
12997                pw.print("  Sticky broadcasts for user ");
12998                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12999                StringBuilder sb = new StringBuilder(128);
13000                for (Map.Entry<String, ArrayList<Intent>> ent
13001                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13002                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13003                    if (dumpAll) {
13004                        pw.println(":");
13005                        ArrayList<Intent> intents = ent.getValue();
13006                        final int N = intents.size();
13007                        for (int i=0; i<N; i++) {
13008                            sb.setLength(0);
13009                            sb.append("    Intent: ");
13010                            intents.get(i).toShortString(sb, false, true, false, false);
13011                            pw.println(sb.toString());
13012                            Bundle bundle = intents.get(i).getExtras();
13013                            if (bundle != null) {
13014                                pw.print("      ");
13015                                pw.println(bundle.toString());
13016                            }
13017                        }
13018                    } else {
13019                        pw.println("");
13020                    }
13021                }
13022            }
13023        }
13024
13025        if (!onlyHistory && dumpAll) {
13026            pw.println();
13027            for (BroadcastQueue queue : mBroadcastQueues) {
13028                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13029                        + queue.mBroadcastsScheduled);
13030            }
13031            pw.println("  mHandler:");
13032            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13033            needSep = true;
13034            printedAnything = true;
13035        }
13036
13037        if (!printedAnything) {
13038            pw.println("  (nothing)");
13039        }
13040    }
13041
13042    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13043            int opti, boolean dumpAll, String dumpPackage) {
13044        boolean needSep;
13045        boolean printedAnything = false;
13046
13047        ItemMatcher matcher = new ItemMatcher();
13048        matcher.build(args, opti);
13049
13050        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13051
13052        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13053        printedAnything |= needSep;
13054
13055        if (mLaunchingProviders.size() > 0) {
13056            boolean printed = false;
13057            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13058                ContentProviderRecord r = mLaunchingProviders.get(i);
13059                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13060                    continue;
13061                }
13062                if (!printed) {
13063                    if (needSep) pw.println();
13064                    needSep = true;
13065                    pw.println("  Launching content providers:");
13066                    printed = true;
13067                    printedAnything = true;
13068                }
13069                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13070                        pw.println(r);
13071            }
13072        }
13073
13074        if (mGrantedUriPermissions.size() > 0) {
13075            boolean printed = false;
13076            int dumpUid = -2;
13077            if (dumpPackage != null) {
13078                try {
13079                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13080                } catch (NameNotFoundException e) {
13081                    dumpUid = -1;
13082                }
13083            }
13084            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13085                int uid = mGrantedUriPermissions.keyAt(i);
13086                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13087                    continue;
13088                }
13089                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13090                if (!printed) {
13091                    if (needSep) pw.println();
13092                    needSep = true;
13093                    pw.println("  Granted Uri Permissions:");
13094                    printed = true;
13095                    printedAnything = true;
13096                }
13097                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13098                for (UriPermission perm : perms.values()) {
13099                    pw.print("    "); pw.println(perm);
13100                    if (dumpAll) {
13101                        perm.dump(pw, "      ");
13102                    }
13103                }
13104            }
13105        }
13106
13107        if (!printedAnything) {
13108            pw.println("  (nothing)");
13109        }
13110    }
13111
13112    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13113            int opti, boolean dumpAll, String dumpPackage) {
13114        boolean printed = false;
13115
13116        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13117
13118        if (mIntentSenderRecords.size() > 0) {
13119            Iterator<WeakReference<PendingIntentRecord>> it
13120                    = mIntentSenderRecords.values().iterator();
13121            while (it.hasNext()) {
13122                WeakReference<PendingIntentRecord> ref = it.next();
13123                PendingIntentRecord rec = ref != null ? ref.get(): null;
13124                if (dumpPackage != null && (rec == null
13125                        || !dumpPackage.equals(rec.key.packageName))) {
13126                    continue;
13127                }
13128                printed = true;
13129                if (rec != null) {
13130                    pw.print("  * "); pw.println(rec);
13131                    if (dumpAll) {
13132                        rec.dump(pw, "    ");
13133                    }
13134                } else {
13135                    pw.print("  * "); pw.println(ref);
13136                }
13137            }
13138        }
13139
13140        if (!printed) {
13141            pw.println("  (nothing)");
13142        }
13143    }
13144
13145    private static final int dumpProcessList(PrintWriter pw,
13146            ActivityManagerService service, List list,
13147            String prefix, String normalLabel, String persistentLabel,
13148            String dumpPackage) {
13149        int numPers = 0;
13150        final int N = list.size()-1;
13151        for (int i=N; i>=0; i--) {
13152            ProcessRecord r = (ProcessRecord)list.get(i);
13153            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13154                continue;
13155            }
13156            pw.println(String.format("%s%s #%2d: %s",
13157                    prefix, (r.persistent ? persistentLabel : normalLabel),
13158                    i, r.toString()));
13159            if (r.persistent) {
13160                numPers++;
13161            }
13162        }
13163        return numPers;
13164    }
13165
13166    private static final boolean dumpProcessOomList(PrintWriter pw,
13167            ActivityManagerService service, List<ProcessRecord> origList,
13168            String prefix, String normalLabel, String persistentLabel,
13169            boolean inclDetails, String dumpPackage) {
13170
13171        ArrayList<Pair<ProcessRecord, Integer>> list
13172                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13173        for (int i=0; i<origList.size(); i++) {
13174            ProcessRecord r = origList.get(i);
13175            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13176                continue;
13177            }
13178            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13179        }
13180
13181        if (list.size() <= 0) {
13182            return false;
13183        }
13184
13185        Comparator<Pair<ProcessRecord, Integer>> comparator
13186                = new Comparator<Pair<ProcessRecord, Integer>>() {
13187            @Override
13188            public int compare(Pair<ProcessRecord, Integer> object1,
13189                    Pair<ProcessRecord, Integer> object2) {
13190                if (object1.first.setAdj != object2.first.setAdj) {
13191                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13192                }
13193                if (object1.second.intValue() != object2.second.intValue()) {
13194                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13195                }
13196                return 0;
13197            }
13198        };
13199
13200        Collections.sort(list, comparator);
13201
13202        final long curRealtime = SystemClock.elapsedRealtime();
13203        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13204        final long curUptime = SystemClock.uptimeMillis();
13205        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13206
13207        for (int i=list.size()-1; i>=0; i--) {
13208            ProcessRecord r = list.get(i).first;
13209            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13210            char schedGroup;
13211            switch (r.setSchedGroup) {
13212                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13213                    schedGroup = 'B';
13214                    break;
13215                case Process.THREAD_GROUP_DEFAULT:
13216                    schedGroup = 'F';
13217                    break;
13218                default:
13219                    schedGroup = '?';
13220                    break;
13221            }
13222            char foreground;
13223            if (r.foregroundActivities) {
13224                foreground = 'A';
13225            } else if (r.foregroundServices) {
13226                foreground = 'S';
13227            } else {
13228                foreground = ' ';
13229            }
13230            String procState = ProcessList.makeProcStateString(r.curProcState);
13231            pw.print(prefix);
13232            pw.print(r.persistent ? persistentLabel : normalLabel);
13233            pw.print(" #");
13234            int num = (origList.size()-1)-list.get(i).second;
13235            if (num < 10) pw.print(' ');
13236            pw.print(num);
13237            pw.print(": ");
13238            pw.print(oomAdj);
13239            pw.print(' ');
13240            pw.print(schedGroup);
13241            pw.print('/');
13242            pw.print(foreground);
13243            pw.print('/');
13244            pw.print(procState);
13245            pw.print(" trm:");
13246            if (r.trimMemoryLevel < 10) pw.print(' ');
13247            pw.print(r.trimMemoryLevel);
13248            pw.print(' ');
13249            pw.print(r.toShortString());
13250            pw.print(" (");
13251            pw.print(r.adjType);
13252            pw.println(')');
13253            if (r.adjSource != null || r.adjTarget != null) {
13254                pw.print(prefix);
13255                pw.print("    ");
13256                if (r.adjTarget instanceof ComponentName) {
13257                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13258                } else if (r.adjTarget != null) {
13259                    pw.print(r.adjTarget.toString());
13260                } else {
13261                    pw.print("{null}");
13262                }
13263                pw.print("<=");
13264                if (r.adjSource instanceof ProcessRecord) {
13265                    pw.print("Proc{");
13266                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13267                    pw.println("}");
13268                } else if (r.adjSource != null) {
13269                    pw.println(r.adjSource.toString());
13270                } else {
13271                    pw.println("{null}");
13272                }
13273            }
13274            if (inclDetails) {
13275                pw.print(prefix);
13276                pw.print("    ");
13277                pw.print("oom: max="); pw.print(r.maxAdj);
13278                pw.print(" curRaw="); pw.print(r.curRawAdj);
13279                pw.print(" setRaw="); pw.print(r.setRawAdj);
13280                pw.print(" cur="); pw.print(r.curAdj);
13281                pw.print(" set="); pw.println(r.setAdj);
13282                pw.print(prefix);
13283                pw.print("    ");
13284                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13285                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13286                pw.print(" lastPss="); pw.print(r.lastPss);
13287                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13288                pw.print(prefix);
13289                pw.print("    ");
13290                pw.print("cached="); pw.print(r.cached);
13291                pw.print(" empty="); pw.print(r.empty);
13292                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13293
13294                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13295                    if (r.lastWakeTime != 0) {
13296                        long wtime;
13297                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13298                        synchronized (stats) {
13299                            wtime = stats.getProcessWakeTime(r.info.uid,
13300                                    r.pid, curRealtime);
13301                        }
13302                        long timeUsed = wtime - r.lastWakeTime;
13303                        pw.print(prefix);
13304                        pw.print("    ");
13305                        pw.print("keep awake over ");
13306                        TimeUtils.formatDuration(realtimeSince, pw);
13307                        pw.print(" used ");
13308                        TimeUtils.formatDuration(timeUsed, pw);
13309                        pw.print(" (");
13310                        pw.print((timeUsed*100)/realtimeSince);
13311                        pw.println("%)");
13312                    }
13313                    if (r.lastCpuTime != 0) {
13314                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13315                        pw.print(prefix);
13316                        pw.print("    ");
13317                        pw.print("run cpu over ");
13318                        TimeUtils.formatDuration(uptimeSince, pw);
13319                        pw.print(" used ");
13320                        TimeUtils.formatDuration(timeUsed, pw);
13321                        pw.print(" (");
13322                        pw.print((timeUsed*100)/uptimeSince);
13323                        pw.println("%)");
13324                    }
13325                }
13326            }
13327        }
13328        return true;
13329    }
13330
13331    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13332            String[] args) {
13333        ArrayList<ProcessRecord> procs;
13334        synchronized (this) {
13335            if (args != null && args.length > start
13336                    && args[start].charAt(0) != '-') {
13337                procs = new ArrayList<ProcessRecord>();
13338                int pid = -1;
13339                try {
13340                    pid = Integer.parseInt(args[start]);
13341                } catch (NumberFormatException e) {
13342                }
13343                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13344                    ProcessRecord proc = mLruProcesses.get(i);
13345                    if (proc.pid == pid) {
13346                        procs.add(proc);
13347                    } else if (allPkgs && proc.pkgList != null
13348                            && proc.pkgList.containsKey(args[start])) {
13349                        procs.add(proc);
13350                    } else if (proc.processName.equals(args[start])) {
13351                        procs.add(proc);
13352                    }
13353                }
13354                if (procs.size() <= 0) {
13355                    return null;
13356                }
13357            } else {
13358                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13359            }
13360        }
13361        return procs;
13362    }
13363
13364    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13365            PrintWriter pw, String[] args) {
13366        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13367        if (procs == null) {
13368            pw.println("No process found for: " + args[0]);
13369            return;
13370        }
13371
13372        long uptime = SystemClock.uptimeMillis();
13373        long realtime = SystemClock.elapsedRealtime();
13374        pw.println("Applications Graphics Acceleration Info:");
13375        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13376
13377        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13378            ProcessRecord r = procs.get(i);
13379            if (r.thread != null) {
13380                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13381                pw.flush();
13382                try {
13383                    TransferPipe tp = new TransferPipe();
13384                    try {
13385                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13386                        tp.go(fd);
13387                    } finally {
13388                        tp.kill();
13389                    }
13390                } catch (IOException e) {
13391                    pw.println("Failure while dumping the app: " + r);
13392                    pw.flush();
13393                } catch (RemoteException e) {
13394                    pw.println("Got a RemoteException while dumping the app " + r);
13395                    pw.flush();
13396                }
13397            }
13398        }
13399    }
13400
13401    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13402        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13403        if (procs == null) {
13404            pw.println("No process found for: " + args[0]);
13405            return;
13406        }
13407
13408        pw.println("Applications Database Info:");
13409
13410        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13411            ProcessRecord r = procs.get(i);
13412            if (r.thread != null) {
13413                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13414                pw.flush();
13415                try {
13416                    TransferPipe tp = new TransferPipe();
13417                    try {
13418                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13419                        tp.go(fd);
13420                    } finally {
13421                        tp.kill();
13422                    }
13423                } catch (IOException e) {
13424                    pw.println("Failure while dumping the app: " + r);
13425                    pw.flush();
13426                } catch (RemoteException e) {
13427                    pw.println("Got a RemoteException while dumping the app " + r);
13428                    pw.flush();
13429                }
13430            }
13431        }
13432    }
13433
13434    final static class MemItem {
13435        final boolean isProc;
13436        final String label;
13437        final String shortLabel;
13438        final long pss;
13439        final int id;
13440        final boolean hasActivities;
13441        ArrayList<MemItem> subitems;
13442
13443        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13444                boolean _hasActivities) {
13445            isProc = true;
13446            label = _label;
13447            shortLabel = _shortLabel;
13448            pss = _pss;
13449            id = _id;
13450            hasActivities = _hasActivities;
13451        }
13452
13453        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13454            isProc = false;
13455            label = _label;
13456            shortLabel = _shortLabel;
13457            pss = _pss;
13458            id = _id;
13459            hasActivities = false;
13460        }
13461    }
13462
13463    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13464            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13465        if (sort && !isCompact) {
13466            Collections.sort(items, new Comparator<MemItem>() {
13467                @Override
13468                public int compare(MemItem lhs, MemItem rhs) {
13469                    if (lhs.pss < rhs.pss) {
13470                        return 1;
13471                    } else if (lhs.pss > rhs.pss) {
13472                        return -1;
13473                    }
13474                    return 0;
13475                }
13476            });
13477        }
13478
13479        for (int i=0; i<items.size(); i++) {
13480            MemItem mi = items.get(i);
13481            if (!isCompact) {
13482                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13483            } else if (mi.isProc) {
13484                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13485                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13486                pw.println(mi.hasActivities ? ",a" : ",e");
13487            } else {
13488                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13489                pw.println(mi.pss);
13490            }
13491            if (mi.subitems != null) {
13492                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13493                        true, isCompact);
13494            }
13495        }
13496    }
13497
13498    // These are in KB.
13499    static final long[] DUMP_MEM_BUCKETS = new long[] {
13500        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13501        120*1024, 160*1024, 200*1024,
13502        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13503        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13504    };
13505
13506    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13507            boolean stackLike) {
13508        int start = label.lastIndexOf('.');
13509        if (start >= 0) start++;
13510        else start = 0;
13511        int end = label.length();
13512        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13513            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13514                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13515                out.append(bucket);
13516                out.append(stackLike ? "MB." : "MB ");
13517                out.append(label, start, end);
13518                return;
13519            }
13520        }
13521        out.append(memKB/1024);
13522        out.append(stackLike ? "MB." : "MB ");
13523        out.append(label, start, end);
13524    }
13525
13526    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13527            ProcessList.NATIVE_ADJ,
13528            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13529            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13530            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13531            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13532            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13533            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13534    };
13535    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13536            "Native",
13537            "System", "Persistent", "Persistent Service", "Foreground",
13538            "Visible", "Perceptible",
13539            "Heavy Weight", "Backup",
13540            "A Services", "Home",
13541            "Previous", "B Services", "Cached"
13542    };
13543    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13544            "native",
13545            "sys", "pers", "persvc", "fore",
13546            "vis", "percept",
13547            "heavy", "backup",
13548            "servicea", "home",
13549            "prev", "serviceb", "cached"
13550    };
13551
13552    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13553            long realtime, boolean isCheckinRequest, boolean isCompact) {
13554        if (isCheckinRequest || isCompact) {
13555            // short checkin version
13556            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13557        } else {
13558            pw.println("Applications Memory Usage (kB):");
13559            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13560        }
13561    }
13562
13563    private static final int KSM_SHARED = 0;
13564    private static final int KSM_SHARING = 1;
13565    private static final int KSM_UNSHARED = 2;
13566    private static final int KSM_VOLATILE = 3;
13567
13568    private final long[] getKsmInfo() {
13569        long[] longOut = new long[4];
13570        final int[] SINGLE_LONG_FORMAT = new int[] {
13571            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13572        };
13573        long[] longTmp = new long[1];
13574        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13575                SINGLE_LONG_FORMAT, null, longTmp, null);
13576        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13577        longTmp[0] = 0;
13578        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13579                SINGLE_LONG_FORMAT, null, longTmp, null);
13580        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13581        longTmp[0] = 0;
13582        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13583                SINGLE_LONG_FORMAT, null, longTmp, null);
13584        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13585        longTmp[0] = 0;
13586        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13587                SINGLE_LONG_FORMAT, null, longTmp, null);
13588        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13589        return longOut;
13590    }
13591
13592    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13593            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13594        boolean dumpDetails = false;
13595        boolean dumpFullDetails = false;
13596        boolean dumpDalvik = false;
13597        boolean oomOnly = false;
13598        boolean isCompact = false;
13599        boolean localOnly = false;
13600        boolean packages = false;
13601
13602        int opti = 0;
13603        while (opti < args.length) {
13604            String opt = args[opti];
13605            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13606                break;
13607            }
13608            opti++;
13609            if ("-a".equals(opt)) {
13610                dumpDetails = true;
13611                dumpFullDetails = true;
13612                dumpDalvik = true;
13613            } else if ("-d".equals(opt)) {
13614                dumpDalvik = true;
13615            } else if ("-c".equals(opt)) {
13616                isCompact = true;
13617            } else if ("--oom".equals(opt)) {
13618                oomOnly = true;
13619            } else if ("--local".equals(opt)) {
13620                localOnly = true;
13621            } else if ("--package".equals(opt)) {
13622                packages = true;
13623            } else if ("-h".equals(opt)) {
13624                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13625                pw.println("  -a: include all available information for each process.");
13626                pw.println("  -d: include dalvik details when dumping process details.");
13627                pw.println("  -c: dump in a compact machine-parseable representation.");
13628                pw.println("  --oom: only show processes organized by oom adj.");
13629                pw.println("  --local: only collect details locally, don't call process.");
13630                pw.println("  --package: interpret process arg as package, dumping all");
13631                pw.println("             processes that have loaded that package.");
13632                pw.println("If [process] is specified it can be the name or ");
13633                pw.println("pid of a specific process to dump.");
13634                return;
13635            } else {
13636                pw.println("Unknown argument: " + opt + "; use -h for help");
13637            }
13638        }
13639
13640        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13641        long uptime = SystemClock.uptimeMillis();
13642        long realtime = SystemClock.elapsedRealtime();
13643        final long[] tmpLong = new long[1];
13644
13645        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13646        if (procs == null) {
13647            // No Java processes.  Maybe they want to print a native process.
13648            if (args != null && args.length > opti
13649                    && args[opti].charAt(0) != '-') {
13650                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13651                        = new ArrayList<ProcessCpuTracker.Stats>();
13652                updateCpuStatsNow();
13653                int findPid = -1;
13654                try {
13655                    findPid = Integer.parseInt(args[opti]);
13656                } catch (NumberFormatException e) {
13657                }
13658                synchronized (mProcessCpuTracker) {
13659                    final int N = mProcessCpuTracker.countStats();
13660                    for (int i=0; i<N; i++) {
13661                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13662                        if (st.pid == findPid || (st.baseName != null
13663                                && st.baseName.equals(args[opti]))) {
13664                            nativeProcs.add(st);
13665                        }
13666                    }
13667                }
13668                if (nativeProcs.size() > 0) {
13669                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13670                            isCompact);
13671                    Debug.MemoryInfo mi = null;
13672                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13673                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13674                        final int pid = r.pid;
13675                        if (!isCheckinRequest && dumpDetails) {
13676                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13677                        }
13678                        if (mi == null) {
13679                            mi = new Debug.MemoryInfo();
13680                        }
13681                        if (dumpDetails || (!brief && !oomOnly)) {
13682                            Debug.getMemoryInfo(pid, mi);
13683                        } else {
13684                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
13685                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13686                        }
13687                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13688                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13689                        if (isCheckinRequest) {
13690                            pw.println();
13691                        }
13692                    }
13693                    return;
13694                }
13695            }
13696            pw.println("No process found for: " + args[opti]);
13697            return;
13698        }
13699
13700        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13701            dumpDetails = true;
13702        }
13703
13704        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13705
13706        String[] innerArgs = new String[args.length-opti];
13707        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13708
13709        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13710        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13711        long nativePss = 0;
13712        long dalvikPss = 0;
13713        long otherPss = 0;
13714        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13715
13716        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13717        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13718                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13719
13720        long totalPss = 0;
13721        long cachedPss = 0;
13722
13723        Debug.MemoryInfo mi = null;
13724        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13725            final ProcessRecord r = procs.get(i);
13726            final IApplicationThread thread;
13727            final int pid;
13728            final int oomAdj;
13729            final boolean hasActivities;
13730            synchronized (this) {
13731                thread = r.thread;
13732                pid = r.pid;
13733                oomAdj = r.getSetAdjWithServices();
13734                hasActivities = r.activities.size() > 0;
13735            }
13736            if (thread != null) {
13737                if (!isCheckinRequest && dumpDetails) {
13738                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13739                }
13740                if (mi == null) {
13741                    mi = new Debug.MemoryInfo();
13742                }
13743                if (dumpDetails || (!brief && !oomOnly)) {
13744                    Debug.getMemoryInfo(pid, mi);
13745                } else {
13746                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
13747                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13748                }
13749                if (dumpDetails) {
13750                    if (localOnly) {
13751                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13752                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13753                        if (isCheckinRequest) {
13754                            pw.println();
13755                        }
13756                    } else {
13757                        try {
13758                            pw.flush();
13759                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13760                                    dumpDalvik, innerArgs);
13761                        } catch (RemoteException e) {
13762                            if (!isCheckinRequest) {
13763                                pw.println("Got RemoteException!");
13764                                pw.flush();
13765                            }
13766                        }
13767                    }
13768                }
13769
13770                final long myTotalPss = mi.getTotalPss();
13771                final long myTotalUss = mi.getTotalUss();
13772
13773                synchronized (this) {
13774                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13775                        // Record this for posterity if the process has been stable.
13776                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13777                    }
13778                }
13779
13780                if (!isCheckinRequest && mi != null) {
13781                    totalPss += myTotalPss;
13782                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13783                            (hasActivities ? " / activities)" : ")"),
13784                            r.processName, myTotalPss, pid, hasActivities);
13785                    procMems.add(pssItem);
13786                    procMemsMap.put(pid, pssItem);
13787
13788                    nativePss += mi.nativePss;
13789                    dalvikPss += mi.dalvikPss;
13790                    otherPss += mi.otherPss;
13791                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13792                        long mem = mi.getOtherPss(j);
13793                        miscPss[j] += mem;
13794                        otherPss -= mem;
13795                    }
13796
13797                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13798                        cachedPss += myTotalPss;
13799                    }
13800
13801                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13802                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13803                                || oomIndex == (oomPss.length-1)) {
13804                            oomPss[oomIndex] += myTotalPss;
13805                            if (oomProcs[oomIndex] == null) {
13806                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13807                            }
13808                            oomProcs[oomIndex].add(pssItem);
13809                            break;
13810                        }
13811                    }
13812                }
13813            }
13814        }
13815
13816        long nativeProcTotalPss = 0;
13817
13818        if (!isCheckinRequest && procs.size() > 1 && !packages) {
13819            // If we are showing aggregations, also look for native processes to
13820            // include so that our aggregations are more accurate.
13821            updateCpuStatsNow();
13822            mi = null;
13823            synchronized (mProcessCpuTracker) {
13824                final int N = mProcessCpuTracker.countStats();
13825                for (int i=0; i<N; i++) {
13826                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13827                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13828                        if (mi == null) {
13829                            mi = new Debug.MemoryInfo();
13830                        }
13831                        if (!brief && !oomOnly) {
13832                            Debug.getMemoryInfo(st.pid, mi);
13833                        } else {
13834                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
13835                            mi.nativePrivateDirty = (int)tmpLong[0];
13836                        }
13837
13838                        final long myTotalPss = mi.getTotalPss();
13839                        totalPss += myTotalPss;
13840                        nativeProcTotalPss += myTotalPss;
13841
13842                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13843                                st.name, myTotalPss, st.pid, false);
13844                        procMems.add(pssItem);
13845
13846                        nativePss += mi.nativePss;
13847                        dalvikPss += mi.dalvikPss;
13848                        otherPss += mi.otherPss;
13849                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13850                            long mem = mi.getOtherPss(j);
13851                            miscPss[j] += mem;
13852                            otherPss -= mem;
13853                        }
13854                        oomPss[0] += myTotalPss;
13855                        if (oomProcs[0] == null) {
13856                            oomProcs[0] = new ArrayList<MemItem>();
13857                        }
13858                        oomProcs[0].add(pssItem);
13859                    }
13860                }
13861            }
13862
13863            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13864
13865            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13866            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13867            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13868            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13869                String label = Debug.MemoryInfo.getOtherLabel(j);
13870                catMems.add(new MemItem(label, label, miscPss[j], j));
13871            }
13872
13873            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13874            for (int j=0; j<oomPss.length; j++) {
13875                if (oomPss[j] != 0) {
13876                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13877                            : DUMP_MEM_OOM_LABEL[j];
13878                    MemItem item = new MemItem(label, label, oomPss[j],
13879                            DUMP_MEM_OOM_ADJ[j]);
13880                    item.subitems = oomProcs[j];
13881                    oomMems.add(item);
13882                }
13883            }
13884
13885            if (!brief && !oomOnly && !isCompact) {
13886                pw.println();
13887                pw.println("Total PSS by process:");
13888                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13889                pw.println();
13890            }
13891            if (!isCompact) {
13892                pw.println("Total PSS by OOM adjustment:");
13893            }
13894            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13895            if (!brief && !oomOnly) {
13896                PrintWriter out = categoryPw != null ? categoryPw : pw;
13897                if (!isCompact) {
13898                    out.println();
13899                    out.println("Total PSS by category:");
13900                }
13901                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13902            }
13903            if (!isCompact) {
13904                pw.println();
13905            }
13906            MemInfoReader memInfo = new MemInfoReader();
13907            memInfo.readMemInfo();
13908            if (nativeProcTotalPss > 0) {
13909                synchronized (this) {
13910                    final long cachedKb = memInfo.getCachedSizeKb();
13911                    final long freeKb = memInfo.getFreeSizeKb();
13912                    final long zramKb = memInfo.getZramTotalSizeKb();
13913                    final long kernelKb = memInfo.getKernelUsedSizeKb();
13914                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
13915                            kernelKb*1024, nativeProcTotalPss*1024);
13916                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
13917                            nativeProcTotalPss);
13918                }
13919            }
13920            if (!brief) {
13921                if (!isCompact) {
13922                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13923                    pw.print(" kB (status ");
13924                    switch (mLastMemoryLevel) {
13925                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13926                            pw.println("normal)");
13927                            break;
13928                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13929                            pw.println("moderate)");
13930                            break;
13931                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13932                            pw.println("low)");
13933                            break;
13934                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13935                            pw.println("critical)");
13936                            break;
13937                        default:
13938                            pw.print(mLastMemoryLevel);
13939                            pw.println(")");
13940                            break;
13941                    }
13942                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13943                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13944                            pw.print(cachedPss); pw.print(" cached pss + ");
13945                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
13946                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13947                } else {
13948                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13949                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13950                            + memInfo.getFreeSizeKb()); pw.print(",");
13951                    pw.println(totalPss - cachedPss);
13952                }
13953            }
13954            if (!isCompact) {
13955                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13956                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
13957                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13958                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
13959                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13960                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13961                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
13962            }
13963            if (!brief) {
13964                if (memInfo.getZramTotalSizeKb() != 0) {
13965                    if (!isCompact) {
13966                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13967                                pw.print(" kB physical used for ");
13968                                pw.print(memInfo.getSwapTotalSizeKb()
13969                                        - memInfo.getSwapFreeSizeKb());
13970                                pw.print(" kB in swap (");
13971                                pw.print(memInfo.getSwapTotalSizeKb());
13972                                pw.println(" kB total swap)");
13973                    } else {
13974                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13975                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13976                                pw.println(memInfo.getSwapFreeSizeKb());
13977                    }
13978                }
13979                final long[] ksm = getKsmInfo();
13980                if (!isCompact) {
13981                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
13982                            || ksm[KSM_VOLATILE] != 0) {
13983                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
13984                                pw.print(" kB saved from shared ");
13985                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
13986                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
13987                                pw.print(" kB unshared; ");
13988                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
13989                    }
13990                    pw.print("   Tuning: ");
13991                    pw.print(ActivityManager.staticGetMemoryClass());
13992                    pw.print(" (large ");
13993                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13994                    pw.print("), oom ");
13995                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13996                    pw.print(" kB");
13997                    pw.print(", restore limit ");
13998                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13999                    pw.print(" kB");
14000                    if (ActivityManager.isLowRamDeviceStatic()) {
14001                        pw.print(" (low-ram)");
14002                    }
14003                    if (ActivityManager.isHighEndGfx()) {
14004                        pw.print(" (high-end-gfx)");
14005                    }
14006                    pw.println();
14007                } else {
14008                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14009                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14010                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14011                    pw.print("tuning,");
14012                    pw.print(ActivityManager.staticGetMemoryClass());
14013                    pw.print(',');
14014                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14015                    pw.print(',');
14016                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14017                    if (ActivityManager.isLowRamDeviceStatic()) {
14018                        pw.print(",low-ram");
14019                    }
14020                    if (ActivityManager.isHighEndGfx()) {
14021                        pw.print(",high-end-gfx");
14022                    }
14023                    pw.println();
14024                }
14025            }
14026        }
14027    }
14028
14029    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14030            long memtrack, String name) {
14031        sb.append("  ");
14032        sb.append(ProcessList.makeOomAdjString(oomAdj));
14033        sb.append(' ');
14034        sb.append(ProcessList.makeProcStateString(procState));
14035        sb.append(' ');
14036        ProcessList.appendRamKb(sb, pss);
14037        sb.append(" kB: ");
14038        sb.append(name);
14039        if (memtrack > 0) {
14040            sb.append(" (");
14041            sb.append(memtrack);
14042            sb.append(" kB memtrack)");
14043        }
14044    }
14045
14046    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14047        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14048        sb.append(" (pid ");
14049        sb.append(mi.pid);
14050        sb.append(") ");
14051        sb.append(mi.adjType);
14052        sb.append('\n');
14053        if (mi.adjReason != null) {
14054            sb.append("                      ");
14055            sb.append(mi.adjReason);
14056            sb.append('\n');
14057        }
14058    }
14059
14060    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14061        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14062        for (int i=0, N=memInfos.size(); i<N; i++) {
14063            ProcessMemInfo mi = memInfos.get(i);
14064            infoMap.put(mi.pid, mi);
14065        }
14066        updateCpuStatsNow();
14067        long[] memtrackTmp = new long[1];
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) {
14073                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14074                    if (pss > 0) {
14075                        if (infoMap.indexOfKey(st.pid) < 0) {
14076                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14077                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14078                            mi.pss = pss;
14079                            mi.memtrack = memtrackTmp[0];
14080                            memInfos.add(mi);
14081                        }
14082                    }
14083                }
14084            }
14085        }
14086
14087        long totalPss = 0;
14088        long totalMemtrack = 0;
14089        for (int i=0, N=memInfos.size(); i<N; i++) {
14090            ProcessMemInfo mi = memInfos.get(i);
14091            if (mi.pss == 0) {
14092                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14093                mi.memtrack = memtrackTmp[0];
14094            }
14095            totalPss += mi.pss;
14096            totalMemtrack += mi.memtrack;
14097        }
14098        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14099            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14100                if (lhs.oomAdj != rhs.oomAdj) {
14101                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14102                }
14103                if (lhs.pss != rhs.pss) {
14104                    return lhs.pss < rhs.pss ? 1 : -1;
14105                }
14106                return 0;
14107            }
14108        });
14109
14110        StringBuilder tag = new StringBuilder(128);
14111        StringBuilder stack = new StringBuilder(128);
14112        tag.append("Low on memory -- ");
14113        appendMemBucket(tag, totalPss, "total", false);
14114        appendMemBucket(stack, totalPss, "total", true);
14115
14116        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14117        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14118        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14119
14120        boolean firstLine = true;
14121        int lastOomAdj = Integer.MIN_VALUE;
14122        long extraNativeRam = 0;
14123        long extraNativeMemtrack = 0;
14124        long cachedPss = 0;
14125        for (int i=0, N=memInfos.size(); i<N; i++) {
14126            ProcessMemInfo mi = memInfos.get(i);
14127
14128            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14129                cachedPss += mi.pss;
14130            }
14131
14132            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14133                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14134                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14135                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14136                if (lastOomAdj != mi.oomAdj) {
14137                    lastOomAdj = mi.oomAdj;
14138                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14139                        tag.append(" / ");
14140                    }
14141                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14142                        if (firstLine) {
14143                            stack.append(":");
14144                            firstLine = false;
14145                        }
14146                        stack.append("\n\t at ");
14147                    } else {
14148                        stack.append("$");
14149                    }
14150                } else {
14151                    tag.append(" ");
14152                    stack.append("$");
14153                }
14154                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14155                    appendMemBucket(tag, mi.pss, mi.name, false);
14156                }
14157                appendMemBucket(stack, mi.pss, mi.name, true);
14158                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14159                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14160                    stack.append("(");
14161                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14162                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14163                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14164                            stack.append(":");
14165                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14166                        }
14167                    }
14168                    stack.append(")");
14169                }
14170            }
14171
14172            appendMemInfo(fullNativeBuilder, mi);
14173            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14174                // The short form only has native processes that are >= 512K.
14175                if (mi.pss >= 512) {
14176                    appendMemInfo(shortNativeBuilder, mi);
14177                } else {
14178                    extraNativeRam += mi.pss;
14179                    extraNativeMemtrack += mi.memtrack;
14180                }
14181            } else {
14182                // Short form has all other details, but if we have collected RAM
14183                // from smaller native processes let's dump a summary of that.
14184                if (extraNativeRam > 0) {
14185                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14186                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14187                    shortNativeBuilder.append('\n');
14188                    extraNativeRam = 0;
14189                }
14190                appendMemInfo(fullJavaBuilder, mi);
14191            }
14192        }
14193
14194        fullJavaBuilder.append("           ");
14195        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14196        fullJavaBuilder.append(" kB: TOTAL");
14197        if (totalMemtrack > 0) {
14198            fullJavaBuilder.append(" (");
14199            fullJavaBuilder.append(totalMemtrack);
14200            fullJavaBuilder.append(" kB memtrack)");
14201        } else {
14202        }
14203        fullJavaBuilder.append("\n");
14204
14205        MemInfoReader memInfo = new MemInfoReader();
14206        memInfo.readMemInfo();
14207        final long[] infos = memInfo.getRawInfo();
14208
14209        StringBuilder memInfoBuilder = new StringBuilder(1024);
14210        Debug.getMemInfo(infos);
14211        memInfoBuilder.append("  MemInfo: ");
14212        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14213        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14214        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14215        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14216        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14217        memInfoBuilder.append("           ");
14218        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14219        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14220        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14221        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14222        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14223            memInfoBuilder.append("  ZRAM: ");
14224            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14225            memInfoBuilder.append(" kB RAM, ");
14226            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14227            memInfoBuilder.append(" kB swap total, ");
14228            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14229            memInfoBuilder.append(" kB swap free\n");
14230        }
14231        final long[] ksm = getKsmInfo();
14232        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14233                || ksm[KSM_VOLATILE] != 0) {
14234            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14235            memInfoBuilder.append(" kB saved from shared ");
14236            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14237            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14238            memInfoBuilder.append(" kB unshared; ");
14239            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14240        }
14241        memInfoBuilder.append("  Free RAM: ");
14242        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14243                + memInfo.getFreeSizeKb());
14244        memInfoBuilder.append(" kB\n");
14245        memInfoBuilder.append("  Used RAM: ");
14246        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14247        memInfoBuilder.append(" kB\n");
14248        memInfoBuilder.append("  Lost RAM: ");
14249        memInfoBuilder.append(memInfo.getTotalSizeKb()
14250                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14251                - memInfo.getKernelUsedSizeKb());
14252        memInfoBuilder.append(" kB\n");
14253        Slog.i(TAG, "Low on memory:");
14254        Slog.i(TAG, shortNativeBuilder.toString());
14255        Slog.i(TAG, fullJavaBuilder.toString());
14256        Slog.i(TAG, memInfoBuilder.toString());
14257
14258        StringBuilder dropBuilder = new StringBuilder(1024);
14259        /*
14260        StringWriter oomSw = new StringWriter();
14261        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14262        StringWriter catSw = new StringWriter();
14263        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14264        String[] emptyArgs = new String[] { };
14265        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14266        oomPw.flush();
14267        String oomString = oomSw.toString();
14268        */
14269        dropBuilder.append("Low on memory:");
14270        dropBuilder.append(stack);
14271        dropBuilder.append('\n');
14272        dropBuilder.append(fullNativeBuilder);
14273        dropBuilder.append(fullJavaBuilder);
14274        dropBuilder.append('\n');
14275        dropBuilder.append(memInfoBuilder);
14276        dropBuilder.append('\n');
14277        /*
14278        dropBuilder.append(oomString);
14279        dropBuilder.append('\n');
14280        */
14281        StringWriter catSw = new StringWriter();
14282        synchronized (ActivityManagerService.this) {
14283            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14284            String[] emptyArgs = new String[] { };
14285            catPw.println();
14286            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14287            catPw.println();
14288            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14289                    false, false, null);
14290            catPw.println();
14291            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14292            catPw.flush();
14293        }
14294        dropBuilder.append(catSw.toString());
14295        addErrorToDropBox("lowmem", null, "system_server", null,
14296                null, tag.toString(), dropBuilder.toString(), null, null);
14297        //Slog.i(TAG, "Sent to dropbox:");
14298        //Slog.i(TAG, dropBuilder.toString());
14299        synchronized (ActivityManagerService.this) {
14300            long now = SystemClock.uptimeMillis();
14301            if (mLastMemUsageReportTime < now) {
14302                mLastMemUsageReportTime = now;
14303            }
14304        }
14305    }
14306
14307    /**
14308     * Searches array of arguments for the specified string
14309     * @param args array of argument strings
14310     * @param value value to search for
14311     * @return true if the value is contained in the array
14312     */
14313    private static boolean scanArgs(String[] args, String value) {
14314        if (args != null) {
14315            for (String arg : args) {
14316                if (value.equals(arg)) {
14317                    return true;
14318                }
14319            }
14320        }
14321        return false;
14322    }
14323
14324    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14325            ContentProviderRecord cpr, boolean always) {
14326        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14327
14328        if (!inLaunching || always) {
14329            synchronized (cpr) {
14330                cpr.launchingApp = null;
14331                cpr.notifyAll();
14332            }
14333            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14334            String names[] = cpr.info.authority.split(";");
14335            for (int j = 0; j < names.length; j++) {
14336                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14337            }
14338        }
14339
14340        for (int i=0; i<cpr.connections.size(); i++) {
14341            ContentProviderConnection conn = cpr.connections.get(i);
14342            if (conn.waiting) {
14343                // If this connection is waiting for the provider, then we don't
14344                // need to mess with its process unless we are always removing
14345                // or for some reason the provider is not currently launching.
14346                if (inLaunching && !always) {
14347                    continue;
14348                }
14349            }
14350            ProcessRecord capp = conn.client;
14351            conn.dead = true;
14352            if (conn.stableCount > 0) {
14353                if (!capp.persistent && capp.thread != null
14354                        && capp.pid != 0
14355                        && capp.pid != MY_PID) {
14356                    capp.kill("depends on provider "
14357                            + cpr.name.flattenToShortString()
14358                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14359                }
14360            } else if (capp.thread != null && conn.provider.provider != null) {
14361                try {
14362                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14363                } catch (RemoteException e) {
14364                }
14365                // In the protocol here, we don't expect the client to correctly
14366                // clean up this connection, we'll just remove it.
14367                cpr.connections.remove(i);
14368                if (conn.client.conProviders.remove(conn)) {
14369                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14370                }
14371            }
14372        }
14373
14374        if (inLaunching && always) {
14375            mLaunchingProviders.remove(cpr);
14376        }
14377        return inLaunching;
14378    }
14379
14380    /**
14381     * Main code for cleaning up a process when it has gone away.  This is
14382     * called both as a result of the process dying, or directly when stopping
14383     * a process when running in single process mode.
14384     *
14385     * @return Returns true if the given process has been restarted, so the
14386     * app that was passed in must remain on the process lists.
14387     */
14388    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14389            boolean restarting, boolean allowRestart, int index) {
14390        if (index >= 0) {
14391            removeLruProcessLocked(app);
14392            ProcessList.remove(app.pid);
14393        }
14394
14395        mProcessesToGc.remove(app);
14396        mPendingPssProcesses.remove(app);
14397
14398        // Dismiss any open dialogs.
14399        if (app.crashDialog != null && !app.forceCrashReport) {
14400            app.crashDialog.dismiss();
14401            app.crashDialog = null;
14402        }
14403        if (app.anrDialog != null) {
14404            app.anrDialog.dismiss();
14405            app.anrDialog = null;
14406        }
14407        if (app.waitDialog != null) {
14408            app.waitDialog.dismiss();
14409            app.waitDialog = null;
14410        }
14411
14412        app.crashing = false;
14413        app.notResponding = false;
14414
14415        app.resetPackageList(mProcessStats);
14416        app.unlinkDeathRecipient();
14417        app.makeInactive(mProcessStats);
14418        app.waitingToKill = null;
14419        app.forcingToForeground = null;
14420        updateProcessForegroundLocked(app, false, false);
14421        app.foregroundActivities = false;
14422        app.hasShownUi = false;
14423        app.treatLikeActivity = false;
14424        app.hasAboveClient = false;
14425        app.hasClientActivities = false;
14426
14427        mServices.killServicesLocked(app, allowRestart);
14428
14429        boolean restart = false;
14430
14431        // Remove published content providers.
14432        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14433            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14434            final boolean always = app.bad || !allowRestart;
14435            if (removeDyingProviderLocked(app, cpr, always) || always) {
14436                // We left the provider in the launching list, need to
14437                // restart it.
14438                restart = true;
14439            }
14440
14441            cpr.provider = null;
14442            cpr.proc = null;
14443        }
14444        app.pubProviders.clear();
14445
14446        // Take care of any launching providers waiting for this process.
14447        if (checkAppInLaunchingProvidersLocked(app, false)) {
14448            restart = true;
14449        }
14450
14451        // Unregister from connected content providers.
14452        if (!app.conProviders.isEmpty()) {
14453            for (int i=0; i<app.conProviders.size(); i++) {
14454                ContentProviderConnection conn = app.conProviders.get(i);
14455                conn.provider.connections.remove(conn);
14456                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
14457                        conn.provider.name);
14458            }
14459            app.conProviders.clear();
14460        }
14461
14462        // At this point there may be remaining entries in mLaunchingProviders
14463        // where we were the only one waiting, so they are no longer of use.
14464        // Look for these and clean up if found.
14465        // XXX Commented out for now.  Trying to figure out a way to reproduce
14466        // the actual situation to identify what is actually going on.
14467        if (false) {
14468            for (int i=0; i<mLaunchingProviders.size(); i++) {
14469                ContentProviderRecord cpr = (ContentProviderRecord)
14470                        mLaunchingProviders.get(i);
14471                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14472                    synchronized (cpr) {
14473                        cpr.launchingApp = null;
14474                        cpr.notifyAll();
14475                    }
14476                }
14477            }
14478        }
14479
14480        skipCurrentReceiverLocked(app);
14481
14482        // Unregister any receivers.
14483        for (int i=app.receivers.size()-1; i>=0; i--) {
14484            removeReceiverLocked(app.receivers.valueAt(i));
14485        }
14486        app.receivers.clear();
14487
14488        // If the app is undergoing backup, tell the backup manager about it
14489        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14490            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14491                    + mBackupTarget.appInfo + " died during backup");
14492            try {
14493                IBackupManager bm = IBackupManager.Stub.asInterface(
14494                        ServiceManager.getService(Context.BACKUP_SERVICE));
14495                bm.agentDisconnected(app.info.packageName);
14496            } catch (RemoteException e) {
14497                // can't happen; backup manager is local
14498            }
14499        }
14500
14501        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14502            ProcessChangeItem item = mPendingProcessChanges.get(i);
14503            if (item.pid == app.pid) {
14504                mPendingProcessChanges.remove(i);
14505                mAvailProcessChanges.add(item);
14506            }
14507        }
14508        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14509
14510        // If the caller is restarting this app, then leave it in its
14511        // current lists and let the caller take care of it.
14512        if (restarting) {
14513            return false;
14514        }
14515
14516        if (!app.persistent || app.isolated) {
14517            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14518                    "Removing non-persistent process during cleanup: " + app);
14519            mProcessNames.remove(app.processName, app.uid);
14520            mIsolatedProcesses.remove(app.uid);
14521            if (mHeavyWeightProcess == app) {
14522                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14523                        mHeavyWeightProcess.userId, 0));
14524                mHeavyWeightProcess = null;
14525            }
14526        } else if (!app.removed) {
14527            // This app is persistent, so we need to keep its record around.
14528            // If it is not already on the pending app list, add it there
14529            // and start a new process for it.
14530            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14531                mPersistentStartingProcesses.add(app);
14532                restart = true;
14533            }
14534        }
14535        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14536                "Clean-up removing on hold: " + app);
14537        mProcessesOnHold.remove(app);
14538
14539        if (app == mHomeProcess) {
14540            mHomeProcess = null;
14541        }
14542        if (app == mPreviousProcess) {
14543            mPreviousProcess = null;
14544        }
14545
14546        if (restart && !app.isolated) {
14547            // We have components that still need to be running in the
14548            // process, so re-launch it.
14549            if (index < 0) {
14550                ProcessList.remove(app.pid);
14551            }
14552            mProcessNames.put(app.processName, app.uid, app);
14553            startProcessLocked(app, "restart", app.processName);
14554            return true;
14555        } else if (app.pid > 0 && app.pid != MY_PID) {
14556            // Goodbye!
14557            boolean removed;
14558            synchronized (mPidsSelfLocked) {
14559                mPidsSelfLocked.remove(app.pid);
14560                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14561            }
14562            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14563            if (app.isolated) {
14564                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14565            }
14566            app.setPid(0);
14567        }
14568        return false;
14569    }
14570
14571    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14572        // Look through the content providers we are waiting to have launched,
14573        // and if any run in this process then either schedule a restart of
14574        // the process or kill the client waiting for it if this process has
14575        // gone bad.
14576        int NL = mLaunchingProviders.size();
14577        boolean restart = false;
14578        for (int i=0; i<NL; i++) {
14579            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14580            if (cpr.launchingApp == app) {
14581                if (!alwaysBad && !app.bad) {
14582                    restart = true;
14583                } else {
14584                    removeDyingProviderLocked(app, cpr, true);
14585                    // cpr should have been removed from mLaunchingProviders
14586                    NL = mLaunchingProviders.size();
14587                    i--;
14588                }
14589            }
14590        }
14591        return restart;
14592    }
14593
14594    // =========================================================
14595    // SERVICES
14596    // =========================================================
14597
14598    @Override
14599    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14600            int flags) {
14601        enforceNotIsolatedCaller("getServices");
14602        synchronized (this) {
14603            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14604        }
14605    }
14606
14607    @Override
14608    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14609        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14610        synchronized (this) {
14611            return mServices.getRunningServiceControlPanelLocked(name);
14612        }
14613    }
14614
14615    @Override
14616    public ComponentName startService(IApplicationThread caller, Intent service,
14617            String resolvedType, int userId) {
14618        enforceNotIsolatedCaller("startService");
14619        // Refuse possible leaked file descriptors
14620        if (service != null && service.hasFileDescriptors() == true) {
14621            throw new IllegalArgumentException("File descriptors passed in Intent");
14622        }
14623
14624        if (DEBUG_SERVICE)
14625            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14626        synchronized(this) {
14627            final int callingPid = Binder.getCallingPid();
14628            final int callingUid = Binder.getCallingUid();
14629            final long origId = Binder.clearCallingIdentity();
14630            ComponentName res = mServices.startServiceLocked(caller, service,
14631                    resolvedType, callingPid, callingUid, userId);
14632            Binder.restoreCallingIdentity(origId);
14633            return res;
14634        }
14635    }
14636
14637    ComponentName startServiceInPackage(int uid,
14638            Intent service, String resolvedType, int userId) {
14639        synchronized(this) {
14640            if (DEBUG_SERVICE)
14641                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14642            final long origId = Binder.clearCallingIdentity();
14643            ComponentName res = mServices.startServiceLocked(null, service,
14644                    resolvedType, -1, uid, userId);
14645            Binder.restoreCallingIdentity(origId);
14646            return res;
14647        }
14648    }
14649
14650    @Override
14651    public int stopService(IApplicationThread caller, Intent service,
14652            String resolvedType, int userId) {
14653        enforceNotIsolatedCaller("stopService");
14654        // Refuse possible leaked file descriptors
14655        if (service != null && service.hasFileDescriptors() == true) {
14656            throw new IllegalArgumentException("File descriptors passed in Intent");
14657        }
14658
14659        synchronized(this) {
14660            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14661        }
14662    }
14663
14664    @Override
14665    public IBinder peekService(Intent service, String resolvedType) {
14666        enforceNotIsolatedCaller("peekService");
14667        // Refuse possible leaked file descriptors
14668        if (service != null && service.hasFileDescriptors() == true) {
14669            throw new IllegalArgumentException("File descriptors passed in Intent");
14670        }
14671        synchronized(this) {
14672            return mServices.peekServiceLocked(service, resolvedType);
14673        }
14674    }
14675
14676    @Override
14677    public boolean stopServiceToken(ComponentName className, IBinder token,
14678            int startId) {
14679        synchronized(this) {
14680            return mServices.stopServiceTokenLocked(className, token, startId);
14681        }
14682    }
14683
14684    @Override
14685    public void setServiceForeground(ComponentName className, IBinder token,
14686            int id, Notification notification, boolean removeNotification) {
14687        synchronized(this) {
14688            mServices.setServiceForegroundLocked(className, token, id, notification,
14689                    removeNotification);
14690        }
14691    }
14692
14693    @Override
14694    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14695            boolean requireFull, String name, String callerPackage) {
14696        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14697                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14698    }
14699
14700    int unsafeConvertIncomingUser(int userId) {
14701        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14702                ? mCurrentUserId : userId;
14703    }
14704
14705    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14706            int allowMode, String name, String callerPackage) {
14707        final int callingUserId = UserHandle.getUserId(callingUid);
14708        if (callingUserId == userId) {
14709            return userId;
14710        }
14711
14712        // Note that we may be accessing mCurrentUserId outside of a lock...
14713        // shouldn't be a big deal, if this is being called outside
14714        // of a locked context there is intrinsically a race with
14715        // the value the caller will receive and someone else changing it.
14716        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14717        // we will switch to the calling user if access to the current user fails.
14718        int targetUserId = unsafeConvertIncomingUser(userId);
14719
14720        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14721            final boolean allow;
14722            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14723                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14724                // If the caller has this permission, they always pass go.  And collect $200.
14725                allow = true;
14726            } else if (allowMode == ALLOW_FULL_ONLY) {
14727                // We require full access, sucks to be you.
14728                allow = false;
14729            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14730                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14731                // If the caller does not have either permission, they are always doomed.
14732                allow = false;
14733            } else if (allowMode == ALLOW_NON_FULL) {
14734                // We are blanket allowing non-full access, you lucky caller!
14735                allow = true;
14736            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14737                // We may or may not allow this depending on whether the two users are
14738                // in the same profile.
14739                synchronized (mUserProfileGroupIdsSelfLocked) {
14740                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14741                            UserInfo.NO_PROFILE_GROUP_ID);
14742                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14743                            UserInfo.NO_PROFILE_GROUP_ID);
14744                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14745                            && callingProfile == targetProfile;
14746                }
14747            } else {
14748                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14749            }
14750            if (!allow) {
14751                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14752                    // In this case, they would like to just execute as their
14753                    // owner user instead of failing.
14754                    targetUserId = callingUserId;
14755                } else {
14756                    StringBuilder builder = new StringBuilder(128);
14757                    builder.append("Permission Denial: ");
14758                    builder.append(name);
14759                    if (callerPackage != null) {
14760                        builder.append(" from ");
14761                        builder.append(callerPackage);
14762                    }
14763                    builder.append(" asks to run as user ");
14764                    builder.append(userId);
14765                    builder.append(" but is calling from user ");
14766                    builder.append(UserHandle.getUserId(callingUid));
14767                    builder.append("; this requires ");
14768                    builder.append(INTERACT_ACROSS_USERS_FULL);
14769                    if (allowMode != ALLOW_FULL_ONLY) {
14770                        builder.append(" or ");
14771                        builder.append(INTERACT_ACROSS_USERS);
14772                    }
14773                    String msg = builder.toString();
14774                    Slog.w(TAG, msg);
14775                    throw new SecurityException(msg);
14776                }
14777            }
14778        }
14779        if (!allowAll && targetUserId < 0) {
14780            throw new IllegalArgumentException(
14781                    "Call does not support special user #" + targetUserId);
14782        }
14783        // Check shell permission
14784        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14785            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14786                    targetUserId)) {
14787                throw new SecurityException("Shell does not have permission to access user "
14788                        + targetUserId + "\n " + Debug.getCallers(3));
14789            }
14790        }
14791        return targetUserId;
14792    }
14793
14794    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14795            String className, int flags) {
14796        boolean result = false;
14797        // For apps that don't have pre-defined UIDs, check for permission
14798        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14799            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14800                if (ActivityManager.checkUidPermission(
14801                        INTERACT_ACROSS_USERS,
14802                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14803                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14804                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14805                            + " requests FLAG_SINGLE_USER, but app does not hold "
14806                            + INTERACT_ACROSS_USERS;
14807                    Slog.w(TAG, msg);
14808                    throw new SecurityException(msg);
14809                }
14810                // Permission passed
14811                result = true;
14812            }
14813        } else if ("system".equals(componentProcessName)) {
14814            result = true;
14815        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14816            // Phone app and persistent apps are allowed to export singleuser providers.
14817            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14818                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14819        }
14820        if (DEBUG_MU) {
14821            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14822                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14823        }
14824        return result;
14825    }
14826
14827    /**
14828     * Checks to see if the caller is in the same app as the singleton
14829     * component, or the component is in a special app. It allows special apps
14830     * to export singleton components but prevents exporting singleton
14831     * components for regular apps.
14832     */
14833    boolean isValidSingletonCall(int callingUid, int componentUid) {
14834        int componentAppId = UserHandle.getAppId(componentUid);
14835        return UserHandle.isSameApp(callingUid, componentUid)
14836                || componentAppId == Process.SYSTEM_UID
14837                || componentAppId == Process.PHONE_UID
14838                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14839                        == PackageManager.PERMISSION_GRANTED;
14840    }
14841
14842    public int bindService(IApplicationThread caller, IBinder token,
14843            Intent service, String resolvedType,
14844            IServiceConnection connection, int flags, int userId) {
14845        enforceNotIsolatedCaller("bindService");
14846
14847        // Refuse possible leaked file descriptors
14848        if (service != null && service.hasFileDescriptors() == true) {
14849            throw new IllegalArgumentException("File descriptors passed in Intent");
14850        }
14851
14852        synchronized(this) {
14853            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14854                    connection, flags, userId);
14855        }
14856    }
14857
14858    public boolean unbindService(IServiceConnection connection) {
14859        synchronized (this) {
14860            return mServices.unbindServiceLocked(connection);
14861        }
14862    }
14863
14864    public void publishService(IBinder token, Intent intent, IBinder service) {
14865        // Refuse possible leaked file descriptors
14866        if (intent != null && intent.hasFileDescriptors() == true) {
14867            throw new IllegalArgumentException("File descriptors passed in Intent");
14868        }
14869
14870        synchronized(this) {
14871            if (!(token instanceof ServiceRecord)) {
14872                throw new IllegalArgumentException("Invalid service token");
14873            }
14874            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14875        }
14876    }
14877
14878    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14879        // Refuse possible leaked file descriptors
14880        if (intent != null && intent.hasFileDescriptors() == true) {
14881            throw new IllegalArgumentException("File descriptors passed in Intent");
14882        }
14883
14884        synchronized(this) {
14885            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14886        }
14887    }
14888
14889    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14890        synchronized(this) {
14891            if (!(token instanceof ServiceRecord)) {
14892                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
14893                throw new IllegalArgumentException("Invalid service token");
14894            }
14895            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14896        }
14897    }
14898
14899    // =========================================================
14900    // BACKUP AND RESTORE
14901    // =========================================================
14902
14903    // Cause the target app to be launched if necessary and its backup agent
14904    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14905    // activity manager to announce its creation.
14906    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14907        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14908        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14909
14910        synchronized(this) {
14911            // !!! TODO: currently no check here that we're already bound
14912            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14913            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14914            synchronized (stats) {
14915                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14916            }
14917
14918            // Backup agent is now in use, its package can't be stopped.
14919            try {
14920                AppGlobals.getPackageManager().setPackageStoppedState(
14921                        app.packageName, false, UserHandle.getUserId(app.uid));
14922            } catch (RemoteException e) {
14923            } catch (IllegalArgumentException e) {
14924                Slog.w(TAG, "Failed trying to unstop package "
14925                        + app.packageName + ": " + e);
14926            }
14927
14928            BackupRecord r = new BackupRecord(ss, app, backupMode);
14929            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14930                    ? new ComponentName(app.packageName, app.backupAgentName)
14931                    : new ComponentName("android", "FullBackupAgent");
14932            // startProcessLocked() returns existing proc's record if it's already running
14933            ProcessRecord proc = startProcessLocked(app.processName, app,
14934                    false, 0, "backup", hostingName, false, false, false);
14935            if (proc == null) {
14936                Slog.e(TAG, "Unable to start backup agent process " + r);
14937                return false;
14938            }
14939
14940            r.app = proc;
14941            mBackupTarget = r;
14942            mBackupAppName = app.packageName;
14943
14944            // Try not to kill the process during backup
14945            updateOomAdjLocked(proc);
14946
14947            // If the process is already attached, schedule the creation of the backup agent now.
14948            // If it is not yet live, this will be done when it attaches to the framework.
14949            if (proc.thread != null) {
14950                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14951                try {
14952                    proc.thread.scheduleCreateBackupAgent(app,
14953                            compatibilityInfoForPackageLocked(app), backupMode);
14954                } catch (RemoteException e) {
14955                    // Will time out on the backup manager side
14956                }
14957            } else {
14958                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14959            }
14960            // Invariants: at this point, the target app process exists and the application
14961            // is either already running or in the process of coming up.  mBackupTarget and
14962            // mBackupAppName describe the app, so that when it binds back to the AM we
14963            // know that it's scheduled for a backup-agent operation.
14964        }
14965
14966        return true;
14967    }
14968
14969    @Override
14970    public void clearPendingBackup() {
14971        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14972        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14973
14974        synchronized (this) {
14975            mBackupTarget = null;
14976            mBackupAppName = null;
14977        }
14978    }
14979
14980    // A backup agent has just come up
14981    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14982        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14983                + " = " + agent);
14984
14985        synchronized(this) {
14986            if (!agentPackageName.equals(mBackupAppName)) {
14987                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14988                return;
14989            }
14990        }
14991
14992        long oldIdent = Binder.clearCallingIdentity();
14993        try {
14994            IBackupManager bm = IBackupManager.Stub.asInterface(
14995                    ServiceManager.getService(Context.BACKUP_SERVICE));
14996            bm.agentConnected(agentPackageName, agent);
14997        } catch (RemoteException e) {
14998            // can't happen; the backup manager service is local
14999        } catch (Exception e) {
15000            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15001            e.printStackTrace();
15002        } finally {
15003            Binder.restoreCallingIdentity(oldIdent);
15004        }
15005    }
15006
15007    // done with this agent
15008    public void unbindBackupAgent(ApplicationInfo appInfo) {
15009        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15010        if (appInfo == null) {
15011            Slog.w(TAG, "unbind backup agent for null app");
15012            return;
15013        }
15014
15015        synchronized(this) {
15016            try {
15017                if (mBackupAppName == null) {
15018                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15019                    return;
15020                }
15021
15022                if (!mBackupAppName.equals(appInfo.packageName)) {
15023                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15024                    return;
15025                }
15026
15027                // Not backing this app up any more; reset its OOM adjustment
15028                final ProcessRecord proc = mBackupTarget.app;
15029                updateOomAdjLocked(proc);
15030
15031                // If the app crashed during backup, 'thread' will be null here
15032                if (proc.thread != null) {
15033                    try {
15034                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15035                                compatibilityInfoForPackageLocked(appInfo));
15036                    } catch (Exception e) {
15037                        Slog.e(TAG, "Exception when unbinding backup agent:");
15038                        e.printStackTrace();
15039                    }
15040                }
15041            } finally {
15042                mBackupTarget = null;
15043                mBackupAppName = null;
15044            }
15045        }
15046    }
15047    // =========================================================
15048    // BROADCASTS
15049    // =========================================================
15050
15051    private final List getStickiesLocked(String action, IntentFilter filter,
15052            List cur, int userId) {
15053        final ContentResolver resolver = mContext.getContentResolver();
15054        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15055        if (stickies == null) {
15056            return cur;
15057        }
15058        final ArrayList<Intent> list = stickies.get(action);
15059        if (list == null) {
15060            return cur;
15061        }
15062        int N = list.size();
15063        for (int i=0; i<N; i++) {
15064            Intent intent = list.get(i);
15065            if (filter.match(resolver, intent, true, TAG) >= 0) {
15066                if (cur == null) {
15067                    cur = new ArrayList<Intent>();
15068                }
15069                cur.add(intent);
15070            }
15071        }
15072        return cur;
15073    }
15074
15075    boolean isPendingBroadcastProcessLocked(int pid) {
15076        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15077                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15078    }
15079
15080    void skipPendingBroadcastLocked(int pid) {
15081            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15082            for (BroadcastQueue queue : mBroadcastQueues) {
15083                queue.skipPendingBroadcastLocked(pid);
15084            }
15085    }
15086
15087    // The app just attached; send any pending broadcasts that it should receive
15088    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15089        boolean didSomething = false;
15090        for (BroadcastQueue queue : mBroadcastQueues) {
15091            didSomething |= queue.sendPendingBroadcastsLocked(app);
15092        }
15093        return didSomething;
15094    }
15095
15096    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15097            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15098        enforceNotIsolatedCaller("registerReceiver");
15099        int callingUid;
15100        int callingPid;
15101        synchronized(this) {
15102            ProcessRecord callerApp = null;
15103            if (caller != null) {
15104                callerApp = getRecordForAppLocked(caller);
15105                if (callerApp == null) {
15106                    throw new SecurityException(
15107                            "Unable to find app for caller " + caller
15108                            + " (pid=" + Binder.getCallingPid()
15109                            + ") when registering receiver " + receiver);
15110                }
15111                if (callerApp.info.uid != Process.SYSTEM_UID &&
15112                        !callerApp.pkgList.containsKey(callerPackage) &&
15113                        !"android".equals(callerPackage)) {
15114                    throw new SecurityException("Given caller package " + callerPackage
15115                            + " is not running in process " + callerApp);
15116                }
15117                callingUid = callerApp.info.uid;
15118                callingPid = callerApp.pid;
15119            } else {
15120                callerPackage = null;
15121                callingUid = Binder.getCallingUid();
15122                callingPid = Binder.getCallingPid();
15123            }
15124
15125            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15126                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15127
15128            List allSticky = null;
15129
15130            // Look for any matching sticky broadcasts...
15131            Iterator actions = filter.actionsIterator();
15132            if (actions != null) {
15133                while (actions.hasNext()) {
15134                    String action = (String)actions.next();
15135                    allSticky = getStickiesLocked(action, filter, allSticky,
15136                            UserHandle.USER_ALL);
15137                    allSticky = getStickiesLocked(action, filter, allSticky,
15138                            UserHandle.getUserId(callingUid));
15139                }
15140            } else {
15141                allSticky = getStickiesLocked(null, filter, allSticky,
15142                        UserHandle.USER_ALL);
15143                allSticky = getStickiesLocked(null, filter, allSticky,
15144                        UserHandle.getUserId(callingUid));
15145            }
15146
15147            // The first sticky in the list is returned directly back to
15148            // the client.
15149            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15150
15151            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15152                    + ": " + sticky);
15153
15154            if (receiver == null) {
15155                return sticky;
15156            }
15157
15158            ReceiverList rl
15159                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15160            if (rl == null) {
15161                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15162                        userId, receiver);
15163                if (rl.app != null) {
15164                    rl.app.receivers.add(rl);
15165                } else {
15166                    try {
15167                        receiver.asBinder().linkToDeath(rl, 0);
15168                    } catch (RemoteException e) {
15169                        return sticky;
15170                    }
15171                    rl.linkedToDeath = true;
15172                }
15173                mRegisteredReceivers.put(receiver.asBinder(), rl);
15174            } else if (rl.uid != callingUid) {
15175                throw new IllegalArgumentException(
15176                        "Receiver requested to register for uid " + callingUid
15177                        + " was previously registered for uid " + rl.uid);
15178            } else if (rl.pid != callingPid) {
15179                throw new IllegalArgumentException(
15180                        "Receiver requested to register for pid " + callingPid
15181                        + " was previously registered for pid " + rl.pid);
15182            } else if (rl.userId != userId) {
15183                throw new IllegalArgumentException(
15184                        "Receiver requested to register for user " + userId
15185                        + " was previously registered for user " + rl.userId);
15186            }
15187            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15188                    permission, callingUid, userId);
15189            rl.add(bf);
15190            if (!bf.debugCheck()) {
15191                Slog.w(TAG, "==> For Dynamic broadast");
15192            }
15193            mReceiverResolver.addFilter(bf);
15194
15195            // Enqueue broadcasts for all existing stickies that match
15196            // this filter.
15197            if (allSticky != null) {
15198                ArrayList receivers = new ArrayList();
15199                receivers.add(bf);
15200
15201                int N = allSticky.size();
15202                for (int i=0; i<N; i++) {
15203                    Intent intent = (Intent)allSticky.get(i);
15204                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15205                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15206                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15207                            null, null, false, true, true, -1);
15208                    queue.enqueueParallelBroadcastLocked(r);
15209                    queue.scheduleBroadcastsLocked();
15210                }
15211            }
15212
15213            return sticky;
15214        }
15215    }
15216
15217    public void unregisterReceiver(IIntentReceiver receiver) {
15218        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15219
15220        final long origId = Binder.clearCallingIdentity();
15221        try {
15222            boolean doTrim = false;
15223
15224            synchronized(this) {
15225                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15226                if (rl != null) {
15227                    final BroadcastRecord r = rl.curBroadcast;
15228                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
15229                        final boolean doNext = r.queue.finishReceiverLocked(
15230                                r, r.resultCode, r.resultData, r.resultExtras,
15231                                r.resultAbort, false);
15232                        if (doNext) {
15233                            doTrim = true;
15234                            r.queue.processNextBroadcast(false);
15235                        }
15236                    }
15237
15238                    if (rl.app != null) {
15239                        rl.app.receivers.remove(rl);
15240                    }
15241                    removeReceiverLocked(rl);
15242                    if (rl.linkedToDeath) {
15243                        rl.linkedToDeath = false;
15244                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15245                    }
15246                }
15247            }
15248
15249            // If we actually concluded any broadcasts, we might now be able
15250            // to trim the recipients' apps from our working set
15251            if (doTrim) {
15252                trimApplications();
15253                return;
15254            }
15255
15256        } finally {
15257            Binder.restoreCallingIdentity(origId);
15258        }
15259    }
15260
15261    void removeReceiverLocked(ReceiverList rl) {
15262        mRegisteredReceivers.remove(rl.receiver.asBinder());
15263        int N = rl.size();
15264        for (int i=0; i<N; i++) {
15265            mReceiverResolver.removeFilter(rl.get(i));
15266        }
15267    }
15268
15269    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15270        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15271            ProcessRecord r = mLruProcesses.get(i);
15272            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15273                try {
15274                    r.thread.dispatchPackageBroadcast(cmd, packages);
15275                } catch (RemoteException ex) {
15276                }
15277            }
15278        }
15279    }
15280
15281    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15282            int callingUid, int[] users) {
15283        List<ResolveInfo> receivers = null;
15284        try {
15285            HashSet<ComponentName> singleUserReceivers = null;
15286            boolean scannedFirstReceivers = false;
15287            for (int user : users) {
15288                // Skip users that have Shell restrictions
15289                if (callingUid == Process.SHELL_UID
15290                        && getUserManagerLocked().hasUserRestriction(
15291                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15292                    continue;
15293                }
15294                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15295                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15296                if (user != 0 && newReceivers != null) {
15297                    // If this is not the primary user, we need to check for
15298                    // any receivers that should be filtered out.
15299                    for (int i=0; i<newReceivers.size(); i++) {
15300                        ResolveInfo ri = newReceivers.get(i);
15301                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15302                            newReceivers.remove(i);
15303                            i--;
15304                        }
15305                    }
15306                }
15307                if (newReceivers != null && newReceivers.size() == 0) {
15308                    newReceivers = null;
15309                }
15310                if (receivers == null) {
15311                    receivers = newReceivers;
15312                } else if (newReceivers != null) {
15313                    // We need to concatenate the additional receivers
15314                    // found with what we have do far.  This would be easy,
15315                    // but we also need to de-dup any receivers that are
15316                    // singleUser.
15317                    if (!scannedFirstReceivers) {
15318                        // Collect any single user receivers we had already retrieved.
15319                        scannedFirstReceivers = true;
15320                        for (int i=0; i<receivers.size(); i++) {
15321                            ResolveInfo ri = receivers.get(i);
15322                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15323                                ComponentName cn = new ComponentName(
15324                                        ri.activityInfo.packageName, ri.activityInfo.name);
15325                                if (singleUserReceivers == null) {
15326                                    singleUserReceivers = new HashSet<ComponentName>();
15327                                }
15328                                singleUserReceivers.add(cn);
15329                            }
15330                        }
15331                    }
15332                    // Add the new results to the existing results, tracking
15333                    // and de-dupping single user receivers.
15334                    for (int i=0; i<newReceivers.size(); i++) {
15335                        ResolveInfo ri = newReceivers.get(i);
15336                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15337                            ComponentName cn = new ComponentName(
15338                                    ri.activityInfo.packageName, ri.activityInfo.name);
15339                            if (singleUserReceivers == null) {
15340                                singleUserReceivers = new HashSet<ComponentName>();
15341                            }
15342                            if (!singleUserReceivers.contains(cn)) {
15343                                singleUserReceivers.add(cn);
15344                                receivers.add(ri);
15345                            }
15346                        } else {
15347                            receivers.add(ri);
15348                        }
15349                    }
15350                }
15351            }
15352        } catch (RemoteException ex) {
15353            // pm is in same process, this will never happen.
15354        }
15355        return receivers;
15356    }
15357
15358    private final int broadcastIntentLocked(ProcessRecord callerApp,
15359            String callerPackage, Intent intent, String resolvedType,
15360            IIntentReceiver resultTo, int resultCode, String resultData,
15361            Bundle map, String requiredPermission, int appOp,
15362            boolean ordered, boolean sticky, int callingPid, int callingUid,
15363            int userId) {
15364        intent = new Intent(intent);
15365
15366        // By default broadcasts do not go to stopped apps.
15367        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15368
15369        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15370            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15371            + " ordered=" + ordered + " userid=" + userId);
15372        if ((resultTo != null) && !ordered) {
15373            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15374        }
15375
15376        userId = handleIncomingUser(callingPid, callingUid, userId,
15377                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15378
15379        // Make sure that the user who is receiving this broadcast is running.
15380        // If not, we will just skip it. Make an exception for shutdown broadcasts
15381        // and upgrade steps.
15382
15383        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15384            if ((callingUid != Process.SYSTEM_UID
15385                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15386                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15387                Slog.w(TAG, "Skipping broadcast of " + intent
15388                        + ": user " + userId + " is stopped");
15389                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15390            }
15391        }
15392
15393        /*
15394         * Prevent non-system code (defined here to be non-persistent
15395         * processes) from sending protected broadcasts.
15396         */
15397        int callingAppId = UserHandle.getAppId(callingUid);
15398        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15399            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15400            || callingAppId == Process.NFC_UID || callingUid == 0) {
15401            // Always okay.
15402        } else if (callerApp == null || !callerApp.persistent) {
15403            try {
15404                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15405                        intent.getAction())) {
15406                    String msg = "Permission Denial: not allowed to send broadcast "
15407                            + intent.getAction() + " from pid="
15408                            + callingPid + ", uid=" + callingUid;
15409                    Slog.w(TAG, msg);
15410                    throw new SecurityException(msg);
15411                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15412                    // Special case for compatibility: we don't want apps to send this,
15413                    // but historically it has not been protected and apps may be using it
15414                    // to poke their own app widget.  So, instead of making it protected,
15415                    // just limit it to the caller.
15416                    if (callerApp == null) {
15417                        String msg = "Permission Denial: not allowed to send broadcast "
15418                                + intent.getAction() + " from unknown caller.";
15419                        Slog.w(TAG, msg);
15420                        throw new SecurityException(msg);
15421                    } else if (intent.getComponent() != null) {
15422                        // They are good enough to send to an explicit component...  verify
15423                        // it is being sent to the calling app.
15424                        if (!intent.getComponent().getPackageName().equals(
15425                                callerApp.info.packageName)) {
15426                            String msg = "Permission Denial: not allowed to send broadcast "
15427                                    + intent.getAction() + " to "
15428                                    + intent.getComponent().getPackageName() + " from "
15429                                    + callerApp.info.packageName;
15430                            Slog.w(TAG, msg);
15431                            throw new SecurityException(msg);
15432                        }
15433                    } else {
15434                        // Limit broadcast to their own package.
15435                        intent.setPackage(callerApp.info.packageName);
15436                    }
15437                }
15438            } catch (RemoteException e) {
15439                Slog.w(TAG, "Remote exception", e);
15440                return ActivityManager.BROADCAST_SUCCESS;
15441            }
15442        }
15443
15444        final String action = intent.getAction();
15445        if (action != null) {
15446            switch (action) {
15447                case Intent.ACTION_UID_REMOVED:
15448                case Intent.ACTION_PACKAGE_REMOVED:
15449                case Intent.ACTION_PACKAGE_CHANGED:
15450                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15451                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15452                    // Handle special intents: if this broadcast is from the package
15453                    // manager about a package being removed, we need to remove all of
15454                    // its activities from the history stack.
15455                    if (checkComponentPermission(
15456                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15457                            callingPid, callingUid, -1, true)
15458                            != PackageManager.PERMISSION_GRANTED) {
15459                        String msg = "Permission Denial: " + intent.getAction()
15460                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15461                                + ", uid=" + callingUid + ")"
15462                                + " requires "
15463                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15464                        Slog.w(TAG, msg);
15465                        throw new SecurityException(msg);
15466                    }
15467                    switch (action) {
15468                        case Intent.ACTION_UID_REMOVED:
15469                            final Bundle intentExtras = intent.getExtras();
15470                            final int uid = intentExtras != null
15471                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15472                            if (uid >= 0) {
15473                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15474                                synchronized (bs) {
15475                                    bs.removeUidStatsLocked(uid);
15476                                }
15477                                mAppOpsService.uidRemoved(uid);
15478                            }
15479                            break;
15480                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15481                            // If resources are unavailable just force stop all those packages
15482                            // and flush the attribute cache as well.
15483                            String list[] =
15484                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15485                            if (list != null && list.length > 0) {
15486                                for (int i = 0; i < list.length; i++) {
15487                                    forceStopPackageLocked(list[i], -1, false, true, true,
15488                                            false, false, userId, "storage unmount");
15489                                }
15490                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
15491                                sendPackageBroadcastLocked(
15492                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15493                                        userId);
15494                            }
15495                            break;
15496                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15497                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
15498                            break;
15499                        case Intent.ACTION_PACKAGE_REMOVED:
15500                        case Intent.ACTION_PACKAGE_CHANGED:
15501                            Uri data = intent.getData();
15502                            String ssp;
15503                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15504                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15505                                boolean fullUninstall = removed &&
15506                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15507                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15508                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15509                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15510                                            false, true, true, false, fullUninstall, userId,
15511                                            removed ? "pkg removed" : "pkg changed");
15512                                }
15513                                if (removed) {
15514                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15515                                            new String[] {ssp}, userId);
15516                                    if (fullUninstall) {
15517                                        mAppOpsService.packageRemoved(
15518                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15519
15520                                        // Remove all permissions granted from/to this package
15521                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15522
15523                                        removeTasksByPackageNameLocked(ssp, userId);
15524                                        if (userId == UserHandle.USER_OWNER) {
15525                                            mTaskPersister.removeFromPackageCache(ssp);
15526                                        }
15527                                    }
15528                                } else {
15529                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15530                                    if (userId == UserHandle.USER_OWNER) {
15531                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15532                                    }
15533                                }
15534                            }
15535                            break;
15536                    }
15537                    break;
15538                case Intent.ACTION_PACKAGE_ADDED:
15539                    // Special case for adding a package: by default turn on compatibility mode.
15540                    Uri data = intent.getData();
15541                    String ssp;
15542                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15543                        final boolean replacing =
15544                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15545                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15546
15547                        if (replacing) {
15548                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15549                        }
15550                        if (userId == UserHandle.USER_OWNER) {
15551                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15552                        }
15553                    }
15554                    break;
15555                case Intent.ACTION_TIMEZONE_CHANGED:
15556                    // If this is the time zone changed action, queue up a message that will reset
15557                    // the timezone of all currently running processes. This message will get
15558                    // queued up before the broadcast happens.
15559                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15560                    break;
15561                case Intent.ACTION_TIME_CHANGED:
15562                    // If the user set the time, let all running processes know.
15563                    final int is24Hour =
15564                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15565                                    : 0;
15566                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15567                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15568                    synchronized (stats) {
15569                        stats.noteCurrentTimeChangedLocked();
15570                    }
15571                    break;
15572                case Intent.ACTION_CLEAR_DNS_CACHE:
15573                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15574                    break;
15575                case Proxy.PROXY_CHANGE_ACTION:
15576                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15577                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15578                    break;
15579            }
15580        }
15581
15582        // Add to the sticky list if requested.
15583        if (sticky) {
15584            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15585                    callingPid, callingUid)
15586                    != PackageManager.PERMISSION_GRANTED) {
15587                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15588                        + callingPid + ", uid=" + callingUid
15589                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15590                Slog.w(TAG, msg);
15591                throw new SecurityException(msg);
15592            }
15593            if (requiredPermission != null) {
15594                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15595                        + " and enforce permission " + requiredPermission);
15596                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15597            }
15598            if (intent.getComponent() != null) {
15599                throw new SecurityException(
15600                        "Sticky broadcasts can't target a specific component");
15601            }
15602            // We use userId directly here, since the "all" target is maintained
15603            // as a separate set of sticky broadcasts.
15604            if (userId != UserHandle.USER_ALL) {
15605                // But first, if this is not a broadcast to all users, then
15606                // make sure it doesn't conflict with an existing broadcast to
15607                // all users.
15608                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15609                        UserHandle.USER_ALL);
15610                if (stickies != null) {
15611                    ArrayList<Intent> list = stickies.get(intent.getAction());
15612                    if (list != null) {
15613                        int N = list.size();
15614                        int i;
15615                        for (i=0; i<N; i++) {
15616                            if (intent.filterEquals(list.get(i))) {
15617                                throw new IllegalArgumentException(
15618                                        "Sticky broadcast " + intent + " for user "
15619                                        + userId + " conflicts with existing global broadcast");
15620                            }
15621                        }
15622                    }
15623                }
15624            }
15625            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15626            if (stickies == null) {
15627                stickies = new ArrayMap<String, ArrayList<Intent>>();
15628                mStickyBroadcasts.put(userId, stickies);
15629            }
15630            ArrayList<Intent> list = stickies.get(intent.getAction());
15631            if (list == null) {
15632                list = new ArrayList<Intent>();
15633                stickies.put(intent.getAction(), list);
15634            }
15635            int N = list.size();
15636            int i;
15637            for (i=0; i<N; i++) {
15638                if (intent.filterEquals(list.get(i))) {
15639                    // This sticky already exists, replace it.
15640                    list.set(i, new Intent(intent));
15641                    break;
15642                }
15643            }
15644            if (i >= N) {
15645                list.add(new Intent(intent));
15646            }
15647        }
15648
15649        int[] users;
15650        if (userId == UserHandle.USER_ALL) {
15651            // Caller wants broadcast to go to all started users.
15652            users = mStartedUserArray;
15653        } else {
15654            // Caller wants broadcast to go to one specific user.
15655            users = new int[] {userId};
15656        }
15657
15658        // Figure out who all will receive this broadcast.
15659        List receivers = null;
15660        List<BroadcastFilter> registeredReceivers = null;
15661        // Need to resolve the intent to interested receivers...
15662        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15663                 == 0) {
15664            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15665        }
15666        if (intent.getComponent() == null) {
15667            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15668                // Query one target user at a time, excluding shell-restricted users
15669                UserManagerService ums = getUserManagerLocked();
15670                for (int i = 0; i < users.length; i++) {
15671                    if (ums.hasUserRestriction(
15672                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15673                        continue;
15674                    }
15675                    List<BroadcastFilter> registeredReceiversForUser =
15676                            mReceiverResolver.queryIntent(intent,
15677                                    resolvedType, false, users[i]);
15678                    if (registeredReceivers == null) {
15679                        registeredReceivers = registeredReceiversForUser;
15680                    } else if (registeredReceiversForUser != null) {
15681                        registeredReceivers.addAll(registeredReceiversForUser);
15682                    }
15683                }
15684            } else {
15685                registeredReceivers = mReceiverResolver.queryIntent(intent,
15686                        resolvedType, false, userId);
15687            }
15688        }
15689
15690        final boolean replacePending =
15691                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15692
15693        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15694                + " replacePending=" + replacePending);
15695
15696        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15697        if (!ordered && NR > 0) {
15698            // If we are not serializing this broadcast, then send the
15699            // registered receivers separately so they don't wait for the
15700            // components to be launched.
15701            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15702            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15703                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15704                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15705                    ordered, sticky, false, userId);
15706            if (DEBUG_BROADCAST) Slog.v(
15707                    TAG, "Enqueueing parallel broadcast " + r);
15708            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15709            if (!replaced) {
15710                queue.enqueueParallelBroadcastLocked(r);
15711                queue.scheduleBroadcastsLocked();
15712            }
15713            registeredReceivers = null;
15714            NR = 0;
15715        }
15716
15717        // Merge into one list.
15718        int ir = 0;
15719        if (receivers != null) {
15720            // A special case for PACKAGE_ADDED: do not allow the package
15721            // being added to see this broadcast.  This prevents them from
15722            // using this as a back door to get run as soon as they are
15723            // installed.  Maybe in the future we want to have a special install
15724            // broadcast or such for apps, but we'd like to deliberately make
15725            // this decision.
15726            String skipPackages[] = null;
15727            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15728                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15729                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15730                Uri data = intent.getData();
15731                if (data != null) {
15732                    String pkgName = data.getSchemeSpecificPart();
15733                    if (pkgName != null) {
15734                        skipPackages = new String[] { pkgName };
15735                    }
15736                }
15737            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15738                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15739            }
15740            if (skipPackages != null && (skipPackages.length > 0)) {
15741                for (String skipPackage : skipPackages) {
15742                    if (skipPackage != null) {
15743                        int NT = receivers.size();
15744                        for (int it=0; it<NT; it++) {
15745                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15746                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15747                                receivers.remove(it);
15748                                it--;
15749                                NT--;
15750                            }
15751                        }
15752                    }
15753                }
15754            }
15755
15756            int NT = receivers != null ? receivers.size() : 0;
15757            int it = 0;
15758            ResolveInfo curt = null;
15759            BroadcastFilter curr = null;
15760            while (it < NT && ir < NR) {
15761                if (curt == null) {
15762                    curt = (ResolveInfo)receivers.get(it);
15763                }
15764                if (curr == null) {
15765                    curr = registeredReceivers.get(ir);
15766                }
15767                if (curr.getPriority() >= curt.priority) {
15768                    // Insert this broadcast record into the final list.
15769                    receivers.add(it, curr);
15770                    ir++;
15771                    curr = null;
15772                    it++;
15773                    NT++;
15774                } else {
15775                    // Skip to the next ResolveInfo in the final list.
15776                    it++;
15777                    curt = null;
15778                }
15779            }
15780        }
15781        while (ir < NR) {
15782            if (receivers == null) {
15783                receivers = new ArrayList();
15784            }
15785            receivers.add(registeredReceivers.get(ir));
15786            ir++;
15787        }
15788
15789        if ((receivers != null && receivers.size() > 0)
15790                || resultTo != null) {
15791            BroadcastQueue queue = broadcastQueueForIntent(intent);
15792            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15793                    callerPackage, callingPid, callingUid, resolvedType,
15794                    requiredPermission, appOp, receivers, resultTo, resultCode,
15795                    resultData, map, ordered, sticky, false, userId);
15796
15797            if (DEBUG_BROADCAST) Slog.v(
15798                    TAG, "Enqueueing ordered broadcast " + r
15799                    + ": prev had " + queue.mOrderedBroadcasts.size());
15800            if (DEBUG_BROADCAST) Slog.i(
15801                    TAG, "Enqueueing broadcast " + r.intent.getAction());
15802
15803            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15804            if (!replaced) {
15805                queue.enqueueOrderedBroadcastLocked(r);
15806                queue.scheduleBroadcastsLocked();
15807            }
15808        }
15809
15810        return ActivityManager.BROADCAST_SUCCESS;
15811    }
15812
15813    final Intent verifyBroadcastLocked(Intent intent) {
15814        // Refuse possible leaked file descriptors
15815        if (intent != null && intent.hasFileDescriptors() == true) {
15816            throw new IllegalArgumentException("File descriptors passed in Intent");
15817        }
15818
15819        int flags = intent.getFlags();
15820
15821        if (!mProcessesReady) {
15822            // if the caller really truly claims to know what they're doing, go
15823            // ahead and allow the broadcast without launching any receivers
15824            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15825                intent = new Intent(intent);
15826                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15827            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15828                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15829                        + " before boot completion");
15830                throw new IllegalStateException("Cannot broadcast before boot completed");
15831            }
15832        }
15833
15834        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15835            throw new IllegalArgumentException(
15836                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15837        }
15838
15839        return intent;
15840    }
15841
15842    public final int broadcastIntent(IApplicationThread caller,
15843            Intent intent, String resolvedType, IIntentReceiver resultTo,
15844            int resultCode, String resultData, Bundle map,
15845            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15846        enforceNotIsolatedCaller("broadcastIntent");
15847        synchronized(this) {
15848            intent = verifyBroadcastLocked(intent);
15849
15850            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15851            final int callingPid = Binder.getCallingPid();
15852            final int callingUid = Binder.getCallingUid();
15853            final long origId = Binder.clearCallingIdentity();
15854            int res = broadcastIntentLocked(callerApp,
15855                    callerApp != null ? callerApp.info.packageName : null,
15856                    intent, resolvedType, resultTo,
15857                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15858                    callingPid, callingUid, userId);
15859            Binder.restoreCallingIdentity(origId);
15860            return res;
15861        }
15862    }
15863
15864    int broadcastIntentInPackage(String packageName, int uid,
15865            Intent intent, String resolvedType, IIntentReceiver resultTo,
15866            int resultCode, String resultData, Bundle map,
15867            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15868        synchronized(this) {
15869            intent = verifyBroadcastLocked(intent);
15870
15871            final long origId = Binder.clearCallingIdentity();
15872            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15873                    resultTo, resultCode, resultData, map, requiredPermission,
15874                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15875            Binder.restoreCallingIdentity(origId);
15876            return res;
15877        }
15878    }
15879
15880    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15881        // Refuse possible leaked file descriptors
15882        if (intent != null && intent.hasFileDescriptors() == true) {
15883            throw new IllegalArgumentException("File descriptors passed in Intent");
15884        }
15885
15886        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15887                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15888
15889        synchronized(this) {
15890            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15891                    != PackageManager.PERMISSION_GRANTED) {
15892                String msg = "Permission Denial: unbroadcastIntent() from pid="
15893                        + Binder.getCallingPid()
15894                        + ", uid=" + Binder.getCallingUid()
15895                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15896                Slog.w(TAG, msg);
15897                throw new SecurityException(msg);
15898            }
15899            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15900            if (stickies != null) {
15901                ArrayList<Intent> list = stickies.get(intent.getAction());
15902                if (list != null) {
15903                    int N = list.size();
15904                    int i;
15905                    for (i=0; i<N; i++) {
15906                        if (intent.filterEquals(list.get(i))) {
15907                            list.remove(i);
15908                            break;
15909                        }
15910                    }
15911                    if (list.size() <= 0) {
15912                        stickies.remove(intent.getAction());
15913                    }
15914                }
15915                if (stickies.size() <= 0) {
15916                    mStickyBroadcasts.remove(userId);
15917                }
15918            }
15919        }
15920    }
15921
15922    void backgroundServicesFinishedLocked(int userId) {
15923        for (BroadcastQueue queue : mBroadcastQueues) {
15924            queue.backgroundServicesFinishedLocked(userId);
15925        }
15926    }
15927
15928    public void finishReceiver(IBinder who, int resultCode, String resultData,
15929            Bundle resultExtras, boolean resultAbort, int flags) {
15930        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15931
15932        // Refuse possible leaked file descriptors
15933        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15934            throw new IllegalArgumentException("File descriptors passed in Bundle");
15935        }
15936
15937        final long origId = Binder.clearCallingIdentity();
15938        try {
15939            boolean doNext = false;
15940            BroadcastRecord r;
15941
15942            synchronized(this) {
15943                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
15944                        ? mFgBroadcastQueue : mBgBroadcastQueue;
15945                r = queue.getMatchingOrderedReceiver(who);
15946                if (r != null) {
15947                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15948                        resultData, resultExtras, resultAbort, true);
15949                }
15950            }
15951
15952            if (doNext) {
15953                r.queue.processNextBroadcast(false);
15954            }
15955            trimApplications();
15956        } finally {
15957            Binder.restoreCallingIdentity(origId);
15958        }
15959    }
15960
15961    // =========================================================
15962    // INSTRUMENTATION
15963    // =========================================================
15964
15965    public boolean startInstrumentation(ComponentName className,
15966            String profileFile, int flags, Bundle arguments,
15967            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15968            int userId, String abiOverride) {
15969        enforceNotIsolatedCaller("startInstrumentation");
15970        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15971                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15972        // Refuse possible leaked file descriptors
15973        if (arguments != null && arguments.hasFileDescriptors()) {
15974            throw new IllegalArgumentException("File descriptors passed in Bundle");
15975        }
15976
15977        synchronized(this) {
15978            InstrumentationInfo ii = null;
15979            ApplicationInfo ai = null;
15980            try {
15981                ii = mContext.getPackageManager().getInstrumentationInfo(
15982                    className, STOCK_PM_FLAGS);
15983                ai = AppGlobals.getPackageManager().getApplicationInfo(
15984                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15985            } catch (PackageManager.NameNotFoundException e) {
15986            } catch (RemoteException e) {
15987            }
15988            if (ii == null) {
15989                reportStartInstrumentationFailure(watcher, className,
15990                        "Unable to find instrumentation info for: " + className);
15991                return false;
15992            }
15993            if (ai == null) {
15994                reportStartInstrumentationFailure(watcher, className,
15995                        "Unable to find instrumentation target package: " + ii.targetPackage);
15996                return false;
15997            }
15998
15999            int match = mContext.getPackageManager().checkSignatures(
16000                    ii.targetPackage, ii.packageName);
16001            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16002                String msg = "Permission Denial: starting instrumentation "
16003                        + className + " from pid="
16004                        + Binder.getCallingPid()
16005                        + ", uid=" + Binder.getCallingPid()
16006                        + " not allowed because package " + ii.packageName
16007                        + " does not have a signature matching the target "
16008                        + ii.targetPackage;
16009                reportStartInstrumentationFailure(watcher, className, msg);
16010                throw new SecurityException(msg);
16011            }
16012
16013            final long origId = Binder.clearCallingIdentity();
16014            // Instrumentation can kill and relaunch even persistent processes
16015            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16016                    "start instr");
16017            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16018            app.instrumentationClass = className;
16019            app.instrumentationInfo = ai;
16020            app.instrumentationProfileFile = profileFile;
16021            app.instrumentationArguments = arguments;
16022            app.instrumentationWatcher = watcher;
16023            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16024            app.instrumentationResultClass = className;
16025            Binder.restoreCallingIdentity(origId);
16026        }
16027
16028        return true;
16029    }
16030
16031    /**
16032     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16033     * error to the logs, but if somebody is watching, send the report there too.  This enables
16034     * the "am" command to report errors with more information.
16035     *
16036     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16037     * @param cn The component name of the instrumentation.
16038     * @param report The error report.
16039     */
16040    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16041            ComponentName cn, String report) {
16042        Slog.w(TAG, report);
16043        try {
16044            if (watcher != null) {
16045                Bundle results = new Bundle();
16046                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16047                results.putString("Error", report);
16048                watcher.instrumentationStatus(cn, -1, results);
16049            }
16050        } catch (RemoteException e) {
16051            Slog.w(TAG, e);
16052        }
16053    }
16054
16055    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16056        if (app.instrumentationWatcher != null) {
16057            try {
16058                // NOTE:  IInstrumentationWatcher *must* be oneway here
16059                app.instrumentationWatcher.instrumentationFinished(
16060                    app.instrumentationClass,
16061                    resultCode,
16062                    results);
16063            } catch (RemoteException e) {
16064            }
16065        }
16066        if (app.instrumentationUiAutomationConnection != null) {
16067            try {
16068                app.instrumentationUiAutomationConnection.shutdown();
16069            } catch (RemoteException re) {
16070                /* ignore */
16071            }
16072            // Only a UiAutomation can set this flag and now that
16073            // it is finished we make sure it is reset to its default.
16074            mUserIsMonkey = false;
16075        }
16076        app.instrumentationWatcher = null;
16077        app.instrumentationUiAutomationConnection = null;
16078        app.instrumentationClass = null;
16079        app.instrumentationInfo = null;
16080        app.instrumentationProfileFile = null;
16081        app.instrumentationArguments = null;
16082
16083        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16084                "finished inst");
16085    }
16086
16087    public void finishInstrumentation(IApplicationThread target,
16088            int resultCode, Bundle results) {
16089        int userId = UserHandle.getCallingUserId();
16090        // Refuse possible leaked file descriptors
16091        if (results != null && results.hasFileDescriptors()) {
16092            throw new IllegalArgumentException("File descriptors passed in Intent");
16093        }
16094
16095        synchronized(this) {
16096            ProcessRecord app = getRecordForAppLocked(target);
16097            if (app == null) {
16098                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16099                return;
16100            }
16101            final long origId = Binder.clearCallingIdentity();
16102            finishInstrumentationLocked(app, resultCode, results);
16103            Binder.restoreCallingIdentity(origId);
16104        }
16105    }
16106
16107    // =========================================================
16108    // CONFIGURATION
16109    // =========================================================
16110
16111    public ConfigurationInfo getDeviceConfigurationInfo() {
16112        ConfigurationInfo config = new ConfigurationInfo();
16113        synchronized (this) {
16114            config.reqTouchScreen = mConfiguration.touchscreen;
16115            config.reqKeyboardType = mConfiguration.keyboard;
16116            config.reqNavigation = mConfiguration.navigation;
16117            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16118                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16119                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16120            }
16121            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16122                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16123                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16124            }
16125            config.reqGlEsVersion = GL_ES_VERSION;
16126        }
16127        return config;
16128    }
16129
16130    ActivityStack getFocusedStack() {
16131        return mStackSupervisor.getFocusedStack();
16132    }
16133
16134    @Override
16135    public int getFocusedStackId() throws RemoteException {
16136        ActivityStack focusedStack = getFocusedStack();
16137        if (focusedStack != null) {
16138            return focusedStack.getStackId();
16139        }
16140        return -1;
16141    }
16142
16143    public Configuration getConfiguration() {
16144        Configuration ci;
16145        synchronized(this) {
16146            ci = new Configuration(mConfiguration);
16147            ci.userSetLocale = false;
16148        }
16149        return ci;
16150    }
16151
16152    public void updatePersistentConfiguration(Configuration values) {
16153        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16154                "updateConfiguration()");
16155        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16156                "updateConfiguration()");
16157        if (values == null) {
16158            throw new NullPointerException("Configuration must not be null");
16159        }
16160
16161        synchronized(this) {
16162            final long origId = Binder.clearCallingIdentity();
16163            updateConfigurationLocked(values, null, true, false);
16164            Binder.restoreCallingIdentity(origId);
16165        }
16166    }
16167
16168    public void updateConfiguration(Configuration values) {
16169        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16170                "updateConfiguration()");
16171
16172        synchronized(this) {
16173            if (values == null && mWindowManager != null) {
16174                // sentinel: fetch the current configuration from the window manager
16175                values = mWindowManager.computeNewConfiguration();
16176            }
16177
16178            if (mWindowManager != null) {
16179                mProcessList.applyDisplaySize(mWindowManager);
16180            }
16181
16182            final long origId = Binder.clearCallingIdentity();
16183            if (values != null) {
16184                Settings.System.clearConfiguration(values);
16185            }
16186            updateConfigurationLocked(values, null, false, false);
16187            Binder.restoreCallingIdentity(origId);
16188        }
16189    }
16190
16191    /**
16192     * Do either or both things: (1) change the current configuration, and (2)
16193     * make sure the given activity is running with the (now) current
16194     * configuration.  Returns true if the activity has been left running, or
16195     * false if <var>starting</var> is being destroyed to match the new
16196     * configuration.
16197     * @param persistent TODO
16198     */
16199    boolean updateConfigurationLocked(Configuration values,
16200            ActivityRecord starting, boolean persistent, boolean initLocale) {
16201        int changes = 0;
16202
16203        if (values != null) {
16204            Configuration newConfig = new Configuration(mConfiguration);
16205            changes = newConfig.updateFrom(values);
16206            if (changes != 0) {
16207                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16208                    Slog.i(TAG, "Updating configuration to: " + values);
16209                }
16210
16211                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16212
16213                if (values.locale != null && !initLocale) {
16214                    saveLocaleLocked(values.locale,
16215                                     !values.locale.equals(mConfiguration.locale),
16216                                     values.userSetLocale);
16217                }
16218
16219                mConfigurationSeq++;
16220                if (mConfigurationSeq <= 0) {
16221                    mConfigurationSeq = 1;
16222                }
16223                newConfig.seq = mConfigurationSeq;
16224                mConfiguration = newConfig;
16225                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16226                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16227                //mUsageStatsService.noteStartConfig(newConfig);
16228
16229                final Configuration configCopy = new Configuration(mConfiguration);
16230
16231                // TODO: If our config changes, should we auto dismiss any currently
16232                // showing dialogs?
16233                mShowDialogs = shouldShowDialogs(newConfig);
16234
16235                AttributeCache ac = AttributeCache.instance();
16236                if (ac != null) {
16237                    ac.updateConfiguration(configCopy);
16238                }
16239
16240                // Make sure all resources in our process are updated
16241                // right now, so that anyone who is going to retrieve
16242                // resource values after we return will be sure to get
16243                // the new ones.  This is especially important during
16244                // boot, where the first config change needs to guarantee
16245                // all resources have that config before following boot
16246                // code is executed.
16247                mSystemThread.applyConfigurationToResources(configCopy);
16248
16249                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16250                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16251                    msg.obj = new Configuration(configCopy);
16252                    mHandler.sendMessage(msg);
16253                }
16254
16255                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16256                    ProcessRecord app = mLruProcesses.get(i);
16257                    try {
16258                        if (app.thread != null) {
16259                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16260                                    + app.processName + " new config " + mConfiguration);
16261                            app.thread.scheduleConfigurationChanged(configCopy);
16262                        }
16263                    } catch (Exception e) {
16264                    }
16265                }
16266                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16267                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16268                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16269                        | Intent.FLAG_RECEIVER_FOREGROUND);
16270                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16271                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16272                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16273                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16274                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16275                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16276                    broadcastIntentLocked(null, null, intent,
16277                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16278                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16279                }
16280            }
16281        }
16282
16283        boolean kept = true;
16284        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16285        // mainStack is null during startup.
16286        if (mainStack != null) {
16287            if (changes != 0 && starting == null) {
16288                // If the configuration changed, and the caller is not already
16289                // in the process of starting an activity, then find the top
16290                // activity to check if its configuration needs to change.
16291                starting = mainStack.topRunningActivityLocked(null);
16292            }
16293
16294            if (starting != null) {
16295                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16296                // And we need to make sure at this point that all other activities
16297                // are made visible with the correct configuration.
16298                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16299            }
16300        }
16301
16302        if (values != null && mWindowManager != null) {
16303            mWindowManager.setNewConfiguration(mConfiguration);
16304        }
16305
16306        return kept;
16307    }
16308
16309    /**
16310     * Decide based on the configuration whether we should shouw the ANR,
16311     * crash, etc dialogs.  The idea is that if there is no affordnace to
16312     * press the on-screen buttons, we shouldn't show the dialog.
16313     *
16314     * A thought: SystemUI might also want to get told about this, the Power
16315     * dialog / global actions also might want different behaviors.
16316     */
16317    private static final boolean shouldShowDialogs(Configuration config) {
16318        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16319                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16320    }
16321
16322    /**
16323     * Save the locale. You must be inside a synchronized (this) block.
16324     */
16325    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16326        final String languageTag = l.toLanguageTag();
16327        if (isDiff) {
16328            SystemProperties.set("user.locale", languageTag);
16329
16330            // TODO: Who uses these ? There are no references to these system
16331            // properties in documents or code. Did the author intend to call
16332            // System.setProperty() instead ? Even that wouldn't have any effect.
16333            SystemProperties.set("user.language", l.getLanguage());
16334            SystemProperties.set("user.region", l.getCountry());
16335        }
16336
16337        if (isPersist) {
16338            SystemProperties.set("persist.sys.locale", languageTag);
16339
16340            // These values are *deprecated*, use persist.sys.locale instead.
16341            //
16342            // TODO: Stop setting these values once all code that references
16343            // them has been removed.
16344            SystemProperties.set("persist.sys.language", l.getLanguage());
16345            SystemProperties.set("persist.sys.country", l.getCountry());
16346            SystemProperties.set("persist.sys.localevar", l.getVariant());
16347
16348            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16349        }
16350    }
16351
16352    @Override
16353    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16354        synchronized (this) {
16355            ActivityRecord srec = ActivityRecord.forToken(token);
16356            if (srec.task != null && srec.task.stack != null) {
16357                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16358            }
16359        }
16360        return false;
16361    }
16362
16363    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16364            Intent resultData) {
16365
16366        synchronized (this) {
16367            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16368            if (stack != null) {
16369                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16370            }
16371            return false;
16372        }
16373    }
16374
16375    public int getLaunchedFromUid(IBinder activityToken) {
16376        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16377        if (srec == null) {
16378            return -1;
16379        }
16380        return srec.launchedFromUid;
16381    }
16382
16383    public String getLaunchedFromPackage(IBinder activityToken) {
16384        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16385        if (srec == null) {
16386            return null;
16387        }
16388        return srec.launchedFromPackage;
16389    }
16390
16391    // =========================================================
16392    // LIFETIME MANAGEMENT
16393    // =========================================================
16394
16395    // Returns which broadcast queue the app is the current [or imminent] receiver
16396    // on, or 'null' if the app is not an active broadcast recipient.
16397    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16398        BroadcastRecord r = app.curReceiver;
16399        if (r != null) {
16400            return r.queue;
16401        }
16402
16403        // It's not the current receiver, but it might be starting up to become one
16404        synchronized (this) {
16405            for (BroadcastQueue queue : mBroadcastQueues) {
16406                r = queue.mPendingBroadcast;
16407                if (r != null && r.curApp == app) {
16408                    // found it; report which queue it's in
16409                    return queue;
16410                }
16411            }
16412        }
16413
16414        return null;
16415    }
16416
16417    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16418            ComponentName targetComponent, String targetProcess) {
16419        if (!mTrackingAssociations) {
16420            return null;
16421        }
16422        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16423                = mAssociations.get(targetUid);
16424        if (components == null) {
16425            components = new ArrayMap<>();
16426            mAssociations.put(targetUid, components);
16427        }
16428        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16429        if (sourceUids == null) {
16430            sourceUids = new SparseArray<>();
16431            components.put(targetComponent, sourceUids);
16432        }
16433        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16434        if (sourceProcesses == null) {
16435            sourceProcesses = new ArrayMap<>();
16436            sourceUids.put(sourceUid, sourceProcesses);
16437        }
16438        Association ass = sourceProcesses.get(sourceProcess);
16439        if (ass == null) {
16440            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
16441                    targetProcess);
16442            sourceProcesses.put(sourceProcess, ass);
16443        }
16444        ass.mCount++;
16445        ass.mNesting++;
16446        if (ass.mNesting == 1) {
16447            ass.mStartTime = SystemClock.uptimeMillis();
16448        }
16449        return ass;
16450    }
16451
16452    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16453            ComponentName targetComponent) {
16454        if (!mTrackingAssociations) {
16455            return;
16456        }
16457        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16458                = mAssociations.get(targetUid);
16459        if (components == null) {
16460            return;
16461        }
16462        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16463        if (sourceUids == null) {
16464            return;
16465        }
16466        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16467        if (sourceProcesses == null) {
16468            return;
16469        }
16470        Association ass = sourceProcesses.get(sourceProcess);
16471        if (ass == null || ass.mNesting <= 0) {
16472            return;
16473        }
16474        ass.mNesting--;
16475        if (ass.mNesting == 0) {
16476            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
16477        }
16478    }
16479
16480    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16481            boolean doingAll, long now) {
16482        if (mAdjSeq == app.adjSeq) {
16483            // This adjustment has already been computed.
16484            return app.curRawAdj;
16485        }
16486
16487        if (app.thread == null) {
16488            app.adjSeq = mAdjSeq;
16489            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16490            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16491            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16492        }
16493
16494        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16495        app.adjSource = null;
16496        app.adjTarget = null;
16497        app.empty = false;
16498        app.cached = false;
16499
16500        final int activitiesSize = app.activities.size();
16501
16502        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16503            // The max adjustment doesn't allow this app to be anything
16504            // below foreground, so it is not worth doing work for it.
16505            app.adjType = "fixed";
16506            app.adjSeq = mAdjSeq;
16507            app.curRawAdj = app.maxAdj;
16508            app.foregroundActivities = false;
16509            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16510            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16511            // System processes can do UI, and when they do we want to have
16512            // them trim their memory after the user leaves the UI.  To
16513            // facilitate this, here we need to determine whether or not it
16514            // is currently showing UI.
16515            app.systemNoUi = true;
16516            if (app == TOP_APP) {
16517                app.systemNoUi = false;
16518            } else if (activitiesSize > 0) {
16519                for (int j = 0; j < activitiesSize; j++) {
16520                    final ActivityRecord r = app.activities.get(j);
16521                    if (r.visible) {
16522                        app.systemNoUi = false;
16523                    }
16524                }
16525            }
16526            if (!app.systemNoUi) {
16527                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16528            }
16529            return (app.curAdj=app.maxAdj);
16530        }
16531
16532        app.systemNoUi = false;
16533
16534        // Determine the importance of the process, starting with most
16535        // important to least, and assign an appropriate OOM adjustment.
16536        int adj;
16537        int schedGroup;
16538        int procState;
16539        boolean foregroundActivities = false;
16540        BroadcastQueue queue;
16541        if (app == TOP_APP) {
16542            // The last app on the list is the foreground app.
16543            adj = ProcessList.FOREGROUND_APP_ADJ;
16544            schedGroup = Process.THREAD_GROUP_DEFAULT;
16545            app.adjType = "top-activity";
16546            foregroundActivities = true;
16547            procState = ActivityManager.PROCESS_STATE_TOP;
16548        } else if (app.instrumentationClass != null) {
16549            // Don't want to kill running instrumentation.
16550            adj = ProcessList.FOREGROUND_APP_ADJ;
16551            schedGroup = Process.THREAD_GROUP_DEFAULT;
16552            app.adjType = "instrumentation";
16553            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16554        } else if ((queue = isReceivingBroadcast(app)) != null) {
16555            // An app that is currently receiving a broadcast also
16556            // counts as being in the foreground for OOM killer purposes.
16557            // It's placed in a sched group based on the nature of the
16558            // broadcast as reflected by which queue it's active in.
16559            adj = ProcessList.FOREGROUND_APP_ADJ;
16560            schedGroup = (queue == mFgBroadcastQueue)
16561                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16562            app.adjType = "broadcast";
16563            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16564        } else if (app.executingServices.size() > 0) {
16565            // An app that is currently executing a service callback also
16566            // counts as being in the foreground.
16567            adj = ProcessList.FOREGROUND_APP_ADJ;
16568            schedGroup = app.execServicesFg ?
16569                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16570            app.adjType = "exec-service";
16571            procState = ActivityManager.PROCESS_STATE_SERVICE;
16572            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16573        } else {
16574            // As far as we know the process is empty.  We may change our mind later.
16575            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16576            // At this point we don't actually know the adjustment.  Use the cached adj
16577            // value that the caller wants us to.
16578            adj = cachedAdj;
16579            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16580            app.cached = true;
16581            app.empty = true;
16582            app.adjType = "cch-empty";
16583        }
16584
16585        // Examine all activities if not already foreground.
16586        if (!foregroundActivities && activitiesSize > 0) {
16587            for (int j = 0; j < activitiesSize; j++) {
16588                final ActivityRecord r = app.activities.get(j);
16589                if (r.app != app) {
16590                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16591                            + app + "?!?");
16592                    continue;
16593                }
16594                if (r.visible) {
16595                    // App has a visible activity; only upgrade adjustment.
16596                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16597                        adj = ProcessList.VISIBLE_APP_ADJ;
16598                        app.adjType = "visible";
16599                    }
16600                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16601                        procState = ActivityManager.PROCESS_STATE_TOP;
16602                    }
16603                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16604                    app.cached = false;
16605                    app.empty = false;
16606                    foregroundActivities = true;
16607                    break;
16608                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16609                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16610                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16611                        app.adjType = "pausing";
16612                    }
16613                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16614                        procState = ActivityManager.PROCESS_STATE_TOP;
16615                    }
16616                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16617                    app.cached = false;
16618                    app.empty = false;
16619                    foregroundActivities = true;
16620                } else if (r.state == ActivityState.STOPPING) {
16621                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16622                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16623                        app.adjType = "stopping";
16624                    }
16625                    // For the process state, we will at this point consider the
16626                    // process to be cached.  It will be cached either as an activity
16627                    // or empty depending on whether the activity is finishing.  We do
16628                    // this so that we can treat the process as cached for purposes of
16629                    // memory trimming (determing current memory level, trim command to
16630                    // send to process) since there can be an arbitrary number of stopping
16631                    // processes and they should soon all go into the cached state.
16632                    if (!r.finishing) {
16633                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16634                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16635                        }
16636                    }
16637                    app.cached = false;
16638                    app.empty = false;
16639                    foregroundActivities = true;
16640                } else {
16641                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16642                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16643                        app.adjType = "cch-act";
16644                    }
16645                }
16646            }
16647        }
16648
16649        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16650            if (app.foregroundServices) {
16651                // The user is aware of this app, so make it visible.
16652                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16653                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16654                app.cached = false;
16655                app.adjType = "fg-service";
16656                schedGroup = Process.THREAD_GROUP_DEFAULT;
16657            } else if (app.forcingToForeground != null) {
16658                // The user is aware of this app, so make it visible.
16659                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16660                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16661                app.cached = false;
16662                app.adjType = "force-fg";
16663                app.adjSource = app.forcingToForeground;
16664                schedGroup = Process.THREAD_GROUP_DEFAULT;
16665            }
16666        }
16667
16668        if (app == mHeavyWeightProcess) {
16669            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16670                // We don't want to kill the current heavy-weight process.
16671                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16672                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16673                app.cached = false;
16674                app.adjType = "heavy";
16675            }
16676            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16677                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16678            }
16679        }
16680
16681        if (app == mHomeProcess) {
16682            if (adj > ProcessList.HOME_APP_ADJ) {
16683                // This process is hosting what we currently consider to be the
16684                // home app, so we don't want to let it go into the background.
16685                adj = ProcessList.HOME_APP_ADJ;
16686                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16687                app.cached = false;
16688                app.adjType = "home";
16689            }
16690            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16691                procState = ActivityManager.PROCESS_STATE_HOME;
16692            }
16693        }
16694
16695        if (app == mPreviousProcess && app.activities.size() > 0) {
16696            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16697                // This was the previous process that showed UI to the user.
16698                // We want to try to keep it around more aggressively, to give
16699                // a good experience around switching between two apps.
16700                adj = ProcessList.PREVIOUS_APP_ADJ;
16701                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16702                app.cached = false;
16703                app.adjType = "previous";
16704            }
16705            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16706                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16707            }
16708        }
16709
16710        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16711                + " reason=" + app.adjType);
16712
16713        // By default, we use the computed adjustment.  It may be changed if
16714        // there are applications dependent on our services or providers, but
16715        // this gives us a baseline and makes sure we don't get into an
16716        // infinite recursion.
16717        app.adjSeq = mAdjSeq;
16718        app.curRawAdj = adj;
16719        app.hasStartedServices = false;
16720
16721        if (mBackupTarget != null && app == mBackupTarget.app) {
16722            // If possible we want to avoid killing apps while they're being backed up
16723            if (adj > ProcessList.BACKUP_APP_ADJ) {
16724                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16725                adj = ProcessList.BACKUP_APP_ADJ;
16726                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16727                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16728                }
16729                app.adjType = "backup";
16730                app.cached = false;
16731            }
16732            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16733                procState = ActivityManager.PROCESS_STATE_BACKUP;
16734            }
16735        }
16736
16737        boolean mayBeTop = false;
16738
16739        for (int is = app.services.size()-1;
16740                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16741                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16742                        || procState > ActivityManager.PROCESS_STATE_TOP);
16743                is--) {
16744            ServiceRecord s = app.services.valueAt(is);
16745            if (s.startRequested) {
16746                app.hasStartedServices = true;
16747                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16748                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16749                }
16750                if (app.hasShownUi && app != mHomeProcess) {
16751                    // If this process has shown some UI, let it immediately
16752                    // go to the LRU list because it may be pretty heavy with
16753                    // UI stuff.  We'll tag it with a label just to help
16754                    // debug and understand what is going on.
16755                    if (adj > ProcessList.SERVICE_ADJ) {
16756                        app.adjType = "cch-started-ui-services";
16757                    }
16758                } else {
16759                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16760                        // This service has seen some activity within
16761                        // recent memory, so we will keep its process ahead
16762                        // of the background processes.
16763                        if (adj > ProcessList.SERVICE_ADJ) {
16764                            adj = ProcessList.SERVICE_ADJ;
16765                            app.adjType = "started-services";
16766                            app.cached = false;
16767                        }
16768                    }
16769                    // If we have let the service slide into the background
16770                    // state, still have some text describing what it is doing
16771                    // even though the service no longer has an impact.
16772                    if (adj > ProcessList.SERVICE_ADJ) {
16773                        app.adjType = "cch-started-services";
16774                    }
16775                }
16776            }
16777            for (int conni = s.connections.size()-1;
16778                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16779                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16780                            || procState > ActivityManager.PROCESS_STATE_TOP);
16781                    conni--) {
16782                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16783                for (int i = 0;
16784                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16785                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16786                                || procState > ActivityManager.PROCESS_STATE_TOP);
16787                        i++) {
16788                    // XXX should compute this based on the max of
16789                    // all connected clients.
16790                    ConnectionRecord cr = clist.get(i);
16791                    if (cr.binding.client == app) {
16792                        // Binding to ourself is not interesting.
16793                        continue;
16794                    }
16795                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16796                        ProcessRecord client = cr.binding.client;
16797                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16798                                TOP_APP, doingAll, now);
16799                        int clientProcState = client.curProcState;
16800                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16801                            // If the other app is cached for any reason, for purposes here
16802                            // we are going to consider it empty.  The specific cached state
16803                            // doesn't propagate except under certain conditions.
16804                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16805                        }
16806                        String adjType = null;
16807                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16808                            // Not doing bind OOM management, so treat
16809                            // this guy more like a started service.
16810                            if (app.hasShownUi && app != mHomeProcess) {
16811                                // If this process has shown some UI, let it immediately
16812                                // go to the LRU list because it may be pretty heavy with
16813                                // UI stuff.  We'll tag it with a label just to help
16814                                // debug and understand what is going on.
16815                                if (adj > clientAdj) {
16816                                    adjType = "cch-bound-ui-services";
16817                                }
16818                                app.cached = false;
16819                                clientAdj = adj;
16820                                clientProcState = procState;
16821                            } else {
16822                                if (now >= (s.lastActivity
16823                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16824                                    // This service has not seen activity within
16825                                    // recent memory, so allow it to drop to the
16826                                    // LRU list if there is no other reason to keep
16827                                    // it around.  We'll also tag it with a label just
16828                                    // to help debug and undertand what is going on.
16829                                    if (adj > clientAdj) {
16830                                        adjType = "cch-bound-services";
16831                                    }
16832                                    clientAdj = adj;
16833                                }
16834                            }
16835                        }
16836                        if (adj > clientAdj) {
16837                            // If this process has recently shown UI, and
16838                            // the process that is binding to it is less
16839                            // important than being visible, then we don't
16840                            // care about the binding as much as we care
16841                            // about letting this process get into the LRU
16842                            // list to be killed and restarted if needed for
16843                            // memory.
16844                            if (app.hasShownUi && app != mHomeProcess
16845                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16846                                adjType = "cch-bound-ui-services";
16847                            } else {
16848                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16849                                        |Context.BIND_IMPORTANT)) != 0) {
16850                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16851                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16852                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16853                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16854                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16855                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16856                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16857                                    adj = clientAdj;
16858                                } else {
16859                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16860                                        adj = ProcessList.VISIBLE_APP_ADJ;
16861                                    }
16862                                }
16863                                if (!client.cached) {
16864                                    app.cached = false;
16865                                }
16866                                adjType = "service";
16867                            }
16868                        }
16869                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16870                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16871                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16872                            }
16873                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16874                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16875                                    // Special handling of clients who are in the top state.
16876                                    // We *may* want to consider this process to be in the
16877                                    // top state as well, but only if there is not another
16878                                    // reason for it to be running.  Being on the top is a
16879                                    // special state, meaning you are specifically running
16880                                    // for the current top app.  If the process is already
16881                                    // running in the background for some other reason, it
16882                                    // is more important to continue considering it to be
16883                                    // in the background state.
16884                                    mayBeTop = true;
16885                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16886                                } else {
16887                                    // Special handling for above-top states (persistent
16888                                    // processes).  These should not bring the current process
16889                                    // into the top state, since they are not on top.  Instead
16890                                    // give them the best state after that.
16891                                    clientProcState =
16892                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16893                                }
16894                            }
16895                        } else {
16896                            if (clientProcState <
16897                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16898                                clientProcState =
16899                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16900                            }
16901                        }
16902                        if (procState > clientProcState) {
16903                            procState = clientProcState;
16904                        }
16905                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16906                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16907                            app.pendingUiClean = true;
16908                        }
16909                        if (adjType != null) {
16910                            app.adjType = adjType;
16911                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16912                                    .REASON_SERVICE_IN_USE;
16913                            app.adjSource = cr.binding.client;
16914                            app.adjSourceProcState = clientProcState;
16915                            app.adjTarget = s.name;
16916                        }
16917                    }
16918                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16919                        app.treatLikeActivity = true;
16920                    }
16921                    final ActivityRecord a = cr.activity;
16922                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16923                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16924                                (a.visible || a.state == ActivityState.RESUMED
16925                                 || a.state == ActivityState.PAUSING)) {
16926                            adj = ProcessList.FOREGROUND_APP_ADJ;
16927                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16928                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16929                            }
16930                            app.cached = false;
16931                            app.adjType = "service";
16932                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16933                                    .REASON_SERVICE_IN_USE;
16934                            app.adjSource = a;
16935                            app.adjSourceProcState = procState;
16936                            app.adjTarget = s.name;
16937                        }
16938                    }
16939                }
16940            }
16941        }
16942
16943        for (int provi = app.pubProviders.size()-1;
16944                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16945                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16946                        || procState > ActivityManager.PROCESS_STATE_TOP);
16947                provi--) {
16948            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16949            for (int i = cpr.connections.size()-1;
16950                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16951                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16952                            || procState > ActivityManager.PROCESS_STATE_TOP);
16953                    i--) {
16954                ContentProviderConnection conn = cpr.connections.get(i);
16955                ProcessRecord client = conn.client;
16956                if (client == app) {
16957                    // Being our own client is not interesting.
16958                    continue;
16959                }
16960                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16961                int clientProcState = client.curProcState;
16962                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16963                    // If the other app is cached for any reason, for purposes here
16964                    // we are going to consider it empty.
16965                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16966                }
16967                if (adj > clientAdj) {
16968                    if (app.hasShownUi && app != mHomeProcess
16969                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16970                        app.adjType = "cch-ui-provider";
16971                    } else {
16972                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16973                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16974                        app.adjType = "provider";
16975                    }
16976                    app.cached &= client.cached;
16977                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16978                            .REASON_PROVIDER_IN_USE;
16979                    app.adjSource = client;
16980                    app.adjSourceProcState = clientProcState;
16981                    app.adjTarget = cpr.name;
16982                }
16983                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16984                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16985                        // Special handling of clients who are in the top state.
16986                        // We *may* want to consider this process to be in the
16987                        // top state as well, but only if there is not another
16988                        // reason for it to be running.  Being on the top is a
16989                        // special state, meaning you are specifically running
16990                        // for the current top app.  If the process is already
16991                        // running in the background for some other reason, it
16992                        // is more important to continue considering it to be
16993                        // in the background state.
16994                        mayBeTop = true;
16995                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16996                    } else {
16997                        // Special handling for above-top states (persistent
16998                        // processes).  These should not bring the current process
16999                        // into the top state, since they are not on top.  Instead
17000                        // give them the best state after that.
17001                        clientProcState =
17002                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17003                    }
17004                }
17005                if (procState > clientProcState) {
17006                    procState = clientProcState;
17007                }
17008                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17009                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17010                }
17011            }
17012            // If the provider has external (non-framework) process
17013            // dependencies, ensure that its adjustment is at least
17014            // FOREGROUND_APP_ADJ.
17015            if (cpr.hasExternalProcessHandles()) {
17016                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17017                    adj = ProcessList.FOREGROUND_APP_ADJ;
17018                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17019                    app.cached = false;
17020                    app.adjType = "provider";
17021                    app.adjTarget = cpr.name;
17022                }
17023                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17024                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17025                }
17026            }
17027        }
17028
17029        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17030            // A client of one of our services or providers is in the top state.  We
17031            // *may* want to be in the top state, but not if we are already running in
17032            // the background for some other reason.  For the decision here, we are going
17033            // to pick out a few specific states that we want to remain in when a client
17034            // is top (states that tend to be longer-term) and otherwise allow it to go
17035            // to the top state.
17036            switch (procState) {
17037                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17038                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17039                case ActivityManager.PROCESS_STATE_SERVICE:
17040                    // These all are longer-term states, so pull them up to the top
17041                    // of the background states, but not all the way to the top state.
17042                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17043                    break;
17044                default:
17045                    // Otherwise, top is a better choice, so take it.
17046                    procState = ActivityManager.PROCESS_STATE_TOP;
17047                    break;
17048            }
17049        }
17050
17051        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17052            if (app.hasClientActivities) {
17053                // This is a cached process, but with client activities.  Mark it so.
17054                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17055                app.adjType = "cch-client-act";
17056            } else if (app.treatLikeActivity) {
17057                // This is a cached process, but somebody wants us to treat it like it has
17058                // an activity, okay!
17059                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17060                app.adjType = "cch-as-act";
17061            }
17062        }
17063
17064        if (adj == ProcessList.SERVICE_ADJ) {
17065            if (doingAll) {
17066                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17067                mNewNumServiceProcs++;
17068                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17069                if (!app.serviceb) {
17070                    // This service isn't far enough down on the LRU list to
17071                    // normally be a B service, but if we are low on RAM and it
17072                    // is large we want to force it down since we would prefer to
17073                    // keep launcher over it.
17074                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17075                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17076                        app.serviceHighRam = true;
17077                        app.serviceb = true;
17078                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17079                    } else {
17080                        mNewNumAServiceProcs++;
17081                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17082                    }
17083                } else {
17084                    app.serviceHighRam = false;
17085                }
17086            }
17087            if (app.serviceb) {
17088                adj = ProcessList.SERVICE_B_ADJ;
17089            }
17090        }
17091
17092        app.curRawAdj = adj;
17093
17094        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17095        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17096        if (adj > app.maxAdj) {
17097            adj = app.maxAdj;
17098            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17099                schedGroup = Process.THREAD_GROUP_DEFAULT;
17100            }
17101        }
17102
17103        // Do final modification to adj.  Everything we do between here and applying
17104        // the final setAdj must be done in this function, because we will also use
17105        // it when computing the final cached adj later.  Note that we don't need to
17106        // worry about this for max adj above, since max adj will always be used to
17107        // keep it out of the cached vaues.
17108        app.curAdj = app.modifyRawOomAdj(adj);
17109        app.curSchedGroup = schedGroup;
17110        app.curProcState = procState;
17111        app.foregroundActivities = foregroundActivities;
17112
17113        return app.curRawAdj;
17114    }
17115
17116    /**
17117     * Record new PSS sample for a process.
17118     */
17119    void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17120        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss*1024, uss*1024);
17121        proc.lastPssTime = now;
17122        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17123        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17124                + ": " + pss + " lastPss=" + proc.lastPss
17125                + " state=" + ProcessList.makeProcStateString(procState));
17126        if (proc.initialIdlePss == 0) {
17127            proc.initialIdlePss = pss;
17128        }
17129        proc.lastPss = pss;
17130        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17131            proc.lastCachedPss = pss;
17132        }
17133    }
17134
17135    /**
17136     * Schedule PSS collection of a process.
17137     */
17138    void requestPssLocked(ProcessRecord proc, int procState) {
17139        if (mPendingPssProcesses.contains(proc)) {
17140            return;
17141        }
17142        if (mPendingPssProcesses.size() == 0) {
17143            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17144        }
17145        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17146        proc.pssProcState = procState;
17147        mPendingPssProcesses.add(proc);
17148    }
17149
17150    /**
17151     * Schedule PSS collection of all processes.
17152     */
17153    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17154        if (!always) {
17155            if (now < (mLastFullPssTime +
17156                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17157                return;
17158            }
17159        }
17160        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17161        mLastFullPssTime = now;
17162        mFullPssPending = true;
17163        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17164        mPendingPssProcesses.clear();
17165        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17166            ProcessRecord app = mLruProcesses.get(i);
17167            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17168                app.pssProcState = app.setProcState;
17169                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17170                        mTestPssMode, isSleeping(), now);
17171                mPendingPssProcesses.add(app);
17172            }
17173        }
17174        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17175    }
17176
17177    public void setTestPssMode(boolean enabled) {
17178        synchronized (this) {
17179            mTestPssMode = enabled;
17180            if (enabled) {
17181                // Whenever we enable the mode, we want to take a snapshot all of current
17182                // process mem use.
17183                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17184            }
17185        }
17186    }
17187
17188    /**
17189     * Ask a given process to GC right now.
17190     */
17191    final void performAppGcLocked(ProcessRecord app) {
17192        try {
17193            app.lastRequestedGc = SystemClock.uptimeMillis();
17194            if (app.thread != null) {
17195                if (app.reportLowMemory) {
17196                    app.reportLowMemory = false;
17197                    app.thread.scheduleLowMemory();
17198                } else {
17199                    app.thread.processInBackground();
17200                }
17201            }
17202        } catch (Exception e) {
17203            // whatever.
17204        }
17205    }
17206
17207    /**
17208     * Returns true if things are idle enough to perform GCs.
17209     */
17210    private final boolean canGcNowLocked() {
17211        boolean processingBroadcasts = false;
17212        for (BroadcastQueue q : mBroadcastQueues) {
17213            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17214                processingBroadcasts = true;
17215            }
17216        }
17217        return !processingBroadcasts
17218                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17219    }
17220
17221    /**
17222     * Perform GCs on all processes that are waiting for it, but only
17223     * if things are idle.
17224     */
17225    final void performAppGcsLocked() {
17226        final int N = mProcessesToGc.size();
17227        if (N <= 0) {
17228            return;
17229        }
17230        if (canGcNowLocked()) {
17231            while (mProcessesToGc.size() > 0) {
17232                ProcessRecord proc = mProcessesToGc.remove(0);
17233                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17234                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17235                            <= SystemClock.uptimeMillis()) {
17236                        // To avoid spamming the system, we will GC processes one
17237                        // at a time, waiting a few seconds between each.
17238                        performAppGcLocked(proc);
17239                        scheduleAppGcsLocked();
17240                        return;
17241                    } else {
17242                        // It hasn't been long enough since we last GCed this
17243                        // process...  put it in the list to wait for its time.
17244                        addProcessToGcListLocked(proc);
17245                        break;
17246                    }
17247                }
17248            }
17249
17250            scheduleAppGcsLocked();
17251        }
17252    }
17253
17254    /**
17255     * If all looks good, perform GCs on all processes waiting for them.
17256     */
17257    final void performAppGcsIfAppropriateLocked() {
17258        if (canGcNowLocked()) {
17259            performAppGcsLocked();
17260            return;
17261        }
17262        // Still not idle, wait some more.
17263        scheduleAppGcsLocked();
17264    }
17265
17266    /**
17267     * Schedule the execution of all pending app GCs.
17268     */
17269    final void scheduleAppGcsLocked() {
17270        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17271
17272        if (mProcessesToGc.size() > 0) {
17273            // Schedule a GC for the time to the next process.
17274            ProcessRecord proc = mProcessesToGc.get(0);
17275            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17276
17277            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17278            long now = SystemClock.uptimeMillis();
17279            if (when < (now+GC_TIMEOUT)) {
17280                when = now + GC_TIMEOUT;
17281            }
17282            mHandler.sendMessageAtTime(msg, when);
17283        }
17284    }
17285
17286    /**
17287     * Add a process to the array of processes waiting to be GCed.  Keeps the
17288     * list in sorted order by the last GC time.  The process can't already be
17289     * on the list.
17290     */
17291    final void addProcessToGcListLocked(ProcessRecord proc) {
17292        boolean added = false;
17293        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17294            if (mProcessesToGc.get(i).lastRequestedGc <
17295                    proc.lastRequestedGc) {
17296                added = true;
17297                mProcessesToGc.add(i+1, proc);
17298                break;
17299            }
17300        }
17301        if (!added) {
17302            mProcessesToGc.add(0, proc);
17303        }
17304    }
17305
17306    /**
17307     * Set up to ask a process to GC itself.  This will either do it
17308     * immediately, or put it on the list of processes to gc the next
17309     * time things are idle.
17310     */
17311    final void scheduleAppGcLocked(ProcessRecord app) {
17312        long now = SystemClock.uptimeMillis();
17313        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17314            return;
17315        }
17316        if (!mProcessesToGc.contains(app)) {
17317            addProcessToGcListLocked(app);
17318            scheduleAppGcsLocked();
17319        }
17320    }
17321
17322    final void checkExcessivePowerUsageLocked(boolean doKills) {
17323        updateCpuStatsNow();
17324
17325        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17326        boolean doWakeKills = doKills;
17327        boolean doCpuKills = doKills;
17328        if (mLastPowerCheckRealtime == 0) {
17329            doWakeKills = false;
17330        }
17331        if (mLastPowerCheckUptime == 0) {
17332            doCpuKills = false;
17333        }
17334        if (stats.isScreenOn()) {
17335            doWakeKills = false;
17336        }
17337        final long curRealtime = SystemClock.elapsedRealtime();
17338        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17339        final long curUptime = SystemClock.uptimeMillis();
17340        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17341        mLastPowerCheckRealtime = curRealtime;
17342        mLastPowerCheckUptime = curUptime;
17343        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17344            doWakeKills = false;
17345        }
17346        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17347            doCpuKills = false;
17348        }
17349        int i = mLruProcesses.size();
17350        while (i > 0) {
17351            i--;
17352            ProcessRecord app = mLruProcesses.get(i);
17353            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17354                long wtime;
17355                synchronized (stats) {
17356                    wtime = stats.getProcessWakeTime(app.info.uid,
17357                            app.pid, curRealtime);
17358                }
17359                long wtimeUsed = wtime - app.lastWakeTime;
17360                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17361                if (DEBUG_POWER) {
17362                    StringBuilder sb = new StringBuilder(128);
17363                    sb.append("Wake for ");
17364                    app.toShortString(sb);
17365                    sb.append(": over ");
17366                    TimeUtils.formatDuration(realtimeSince, sb);
17367                    sb.append(" used ");
17368                    TimeUtils.formatDuration(wtimeUsed, sb);
17369                    sb.append(" (");
17370                    sb.append((wtimeUsed*100)/realtimeSince);
17371                    sb.append("%)");
17372                    Slog.i(TAG, sb.toString());
17373                    sb.setLength(0);
17374                    sb.append("CPU for ");
17375                    app.toShortString(sb);
17376                    sb.append(": over ");
17377                    TimeUtils.formatDuration(uptimeSince, sb);
17378                    sb.append(" used ");
17379                    TimeUtils.formatDuration(cputimeUsed, sb);
17380                    sb.append(" (");
17381                    sb.append((cputimeUsed*100)/uptimeSince);
17382                    sb.append("%)");
17383                    Slog.i(TAG, sb.toString());
17384                }
17385                // If a process has held a wake lock for more
17386                // than 50% of the time during this period,
17387                // that sounds bad.  Kill!
17388                if (doWakeKills && realtimeSince > 0
17389                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17390                    synchronized (stats) {
17391                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17392                                realtimeSince, wtimeUsed);
17393                    }
17394                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17395                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17396                } else if (doCpuKills && uptimeSince > 0
17397                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17398                    synchronized (stats) {
17399                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17400                                uptimeSince, cputimeUsed);
17401                    }
17402                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17403                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17404                } else {
17405                    app.lastWakeTime = wtime;
17406                    app.lastCpuTime = app.curCpuTime;
17407                }
17408            }
17409        }
17410    }
17411
17412    private final boolean applyOomAdjLocked(ProcessRecord app,
17413            ProcessRecord TOP_APP, boolean doingAll, long now) {
17414        boolean success = true;
17415
17416        if (app.curRawAdj != app.setRawAdj) {
17417            app.setRawAdj = app.curRawAdj;
17418        }
17419
17420        int changes = 0;
17421
17422        if (app.curAdj != app.setAdj) {
17423            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17424            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17425                TAG, "Set " + app.pid + " " + app.processName +
17426                " adj " + app.curAdj + ": " + app.adjType);
17427            app.setAdj = app.curAdj;
17428        }
17429
17430        if (app.setSchedGroup != app.curSchedGroup) {
17431            app.setSchedGroup = app.curSchedGroup;
17432            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17433                    "Setting process group of " + app.processName
17434                    + " to " + app.curSchedGroup);
17435            if (app.waitingToKill != null &&
17436                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17437                app.kill(app.waitingToKill, true);
17438                success = false;
17439            } else {
17440                if (true) {
17441                    long oldId = Binder.clearCallingIdentity();
17442                    try {
17443                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17444                    } catch (Exception e) {
17445                        Slog.w(TAG, "Failed setting process group of " + app.pid
17446                                + " to " + app.curSchedGroup);
17447                        e.printStackTrace();
17448                    } finally {
17449                        Binder.restoreCallingIdentity(oldId);
17450                    }
17451                } else {
17452                    if (app.thread != null) {
17453                        try {
17454                            app.thread.setSchedulingGroup(app.curSchedGroup);
17455                        } catch (RemoteException e) {
17456                        }
17457                    }
17458                }
17459                Process.setSwappiness(app.pid,
17460                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17461            }
17462        }
17463        if (app.repForegroundActivities != app.foregroundActivities) {
17464            app.repForegroundActivities = app.foregroundActivities;
17465            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17466        }
17467        if (app.repProcState != app.curProcState) {
17468            app.repProcState = app.curProcState;
17469            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17470            if (app.thread != null) {
17471                try {
17472                    if (false) {
17473                        //RuntimeException h = new RuntimeException("here");
17474                        Slog.i(TAG, "Sending new process state " + app.repProcState
17475                                + " to " + app /*, h*/);
17476                    }
17477                    app.thread.setProcessState(app.repProcState);
17478                } catch (RemoteException e) {
17479                }
17480            }
17481        }
17482        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17483                app.setProcState)) {
17484            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17485                // Experimental code to more aggressively collect pss while
17486                // running test...  the problem is that this tends to collect
17487                // the data right when a process is transitioning between process
17488                // states, which well tend to give noisy data.
17489                long start = SystemClock.uptimeMillis();
17490                long pss = Debug.getPss(app.pid, mTmpLong, null);
17491                recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
17492                mPendingPssProcesses.remove(app);
17493                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17494                        + " to " + app.curProcState + ": "
17495                        + (SystemClock.uptimeMillis()-start) + "ms");
17496            }
17497            app.lastStateTime = now;
17498            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17499                    mTestPssMode, isSleeping(), now);
17500            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17501                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17502                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17503                    + (app.nextPssTime-now) + ": " + app);
17504        } else {
17505            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17506                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
17507                    mTestPssMode)))) {
17508                requestPssLocked(app, app.setProcState);
17509                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17510                        mTestPssMode, isSleeping(), now);
17511            } else if (false && DEBUG_PSS) {
17512                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17513            }
17514        }
17515        if (app.setProcState != app.curProcState) {
17516            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17517                    "Proc state change of " + app.processName
17518                    + " to " + app.curProcState);
17519            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17520            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17521            if (setImportant && !curImportant) {
17522                // This app is no longer something we consider important enough to allow to
17523                // use arbitrary amounts of battery power.  Note
17524                // its current wake lock time to later know to kill it if
17525                // it is not behaving well.
17526                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17527                synchronized (stats) {
17528                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17529                            app.pid, SystemClock.elapsedRealtime());
17530                }
17531                app.lastCpuTime = app.curCpuTime;
17532
17533            }
17534            app.setProcState = app.curProcState;
17535            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17536                app.notCachedSinceIdle = false;
17537            }
17538            if (!doingAll) {
17539                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17540            } else {
17541                app.procStateChanged = true;
17542            }
17543        }
17544
17545        if (changes != 0) {
17546            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17547            int i = mPendingProcessChanges.size()-1;
17548            ProcessChangeItem item = null;
17549            while (i >= 0) {
17550                item = mPendingProcessChanges.get(i);
17551                if (item.pid == app.pid) {
17552                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17553                    break;
17554                }
17555                i--;
17556            }
17557            if (i < 0) {
17558                // No existing item in pending changes; need a new one.
17559                final int NA = mAvailProcessChanges.size();
17560                if (NA > 0) {
17561                    item = mAvailProcessChanges.remove(NA-1);
17562                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17563                } else {
17564                    item = new ProcessChangeItem();
17565                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17566                }
17567                item.changes = 0;
17568                item.pid = app.pid;
17569                item.uid = app.info.uid;
17570                if (mPendingProcessChanges.size() == 0) {
17571                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17572                            "*** Enqueueing dispatch processes changed!");
17573                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17574                }
17575                mPendingProcessChanges.add(item);
17576            }
17577            item.changes |= changes;
17578            item.processState = app.repProcState;
17579            item.foregroundActivities = app.repForegroundActivities;
17580            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17581                    + Integer.toHexString(System.identityHashCode(item))
17582                    + " " + app.toShortString() + ": changes=" + item.changes
17583                    + " procState=" + item.processState
17584                    + " foreground=" + item.foregroundActivities
17585                    + " type=" + app.adjType + " source=" + app.adjSource
17586                    + " target=" + app.adjTarget);
17587        }
17588
17589        return success;
17590    }
17591
17592    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17593        if (proc.thread != null) {
17594            if (proc.baseProcessTracker != null) {
17595                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17596            }
17597            if (proc.repProcState >= 0) {
17598                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17599                        proc.repProcState);
17600            }
17601        }
17602    }
17603
17604    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17605            ProcessRecord TOP_APP, boolean doingAll, long now) {
17606        if (app.thread == null) {
17607            return false;
17608        }
17609
17610        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17611
17612        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17613    }
17614
17615    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17616            boolean oomAdj) {
17617        if (isForeground != proc.foregroundServices) {
17618            proc.foregroundServices = isForeground;
17619            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17620                    proc.info.uid);
17621            if (isForeground) {
17622                if (curProcs == null) {
17623                    curProcs = new ArrayList<ProcessRecord>();
17624                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17625                }
17626                if (!curProcs.contains(proc)) {
17627                    curProcs.add(proc);
17628                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17629                            proc.info.packageName, proc.info.uid);
17630                }
17631            } else {
17632                if (curProcs != null) {
17633                    if (curProcs.remove(proc)) {
17634                        mBatteryStatsService.noteEvent(
17635                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17636                                proc.info.packageName, proc.info.uid);
17637                        if (curProcs.size() <= 0) {
17638                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17639                        }
17640                    }
17641                }
17642            }
17643            if (oomAdj) {
17644                updateOomAdjLocked();
17645            }
17646        }
17647    }
17648
17649    private final ActivityRecord resumedAppLocked() {
17650        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17651        String pkg;
17652        int uid;
17653        if (act != null) {
17654            pkg = act.packageName;
17655            uid = act.info.applicationInfo.uid;
17656        } else {
17657            pkg = null;
17658            uid = -1;
17659        }
17660        // Has the UID or resumed package name changed?
17661        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17662                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17663            if (mCurResumedPackage != null) {
17664                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17665                        mCurResumedPackage, mCurResumedUid);
17666            }
17667            mCurResumedPackage = pkg;
17668            mCurResumedUid = uid;
17669            if (mCurResumedPackage != null) {
17670                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17671                        mCurResumedPackage, mCurResumedUid);
17672            }
17673        }
17674        return act;
17675    }
17676
17677    final boolean updateOomAdjLocked(ProcessRecord app) {
17678        final ActivityRecord TOP_ACT = resumedAppLocked();
17679        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17680        final boolean wasCached = app.cached;
17681
17682        mAdjSeq++;
17683
17684        // This is the desired cached adjusment we want to tell it to use.
17685        // If our app is currently cached, we know it, and that is it.  Otherwise,
17686        // we don't know it yet, and it needs to now be cached we will then
17687        // need to do a complete oom adj.
17688        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17689                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17690        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17691                SystemClock.uptimeMillis());
17692        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17693            // Changed to/from cached state, so apps after it in the LRU
17694            // list may also be changed.
17695            updateOomAdjLocked();
17696        }
17697        return success;
17698    }
17699
17700    final void updateOomAdjLocked() {
17701        final ActivityRecord TOP_ACT = resumedAppLocked();
17702        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17703        final long now = SystemClock.uptimeMillis();
17704        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17705        final int N = mLruProcesses.size();
17706
17707        if (false) {
17708            RuntimeException e = new RuntimeException();
17709            e.fillInStackTrace();
17710            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17711        }
17712
17713        mAdjSeq++;
17714        mNewNumServiceProcs = 0;
17715        mNewNumAServiceProcs = 0;
17716
17717        final int emptyProcessLimit;
17718        final int cachedProcessLimit;
17719        if (mProcessLimit <= 0) {
17720            emptyProcessLimit = cachedProcessLimit = 0;
17721        } else if (mProcessLimit == 1) {
17722            emptyProcessLimit = 1;
17723            cachedProcessLimit = 0;
17724        } else {
17725            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17726            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17727        }
17728
17729        // Let's determine how many processes we have running vs.
17730        // how many slots we have for background processes; we may want
17731        // to put multiple processes in a slot of there are enough of
17732        // them.
17733        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17734                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17735        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17736        if (numEmptyProcs > cachedProcessLimit) {
17737            // If there are more empty processes than our limit on cached
17738            // processes, then use the cached process limit for the factor.
17739            // This ensures that the really old empty processes get pushed
17740            // down to the bottom, so if we are running low on memory we will
17741            // have a better chance at keeping around more cached processes
17742            // instead of a gazillion empty processes.
17743            numEmptyProcs = cachedProcessLimit;
17744        }
17745        int emptyFactor = numEmptyProcs/numSlots;
17746        if (emptyFactor < 1) emptyFactor = 1;
17747        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17748        if (cachedFactor < 1) cachedFactor = 1;
17749        int stepCached = 0;
17750        int stepEmpty = 0;
17751        int numCached = 0;
17752        int numEmpty = 0;
17753        int numTrimming = 0;
17754
17755        mNumNonCachedProcs = 0;
17756        mNumCachedHiddenProcs = 0;
17757
17758        // First update the OOM adjustment for each of the
17759        // application processes based on their current state.
17760        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17761        int nextCachedAdj = curCachedAdj+1;
17762        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17763        int nextEmptyAdj = curEmptyAdj+2;
17764        for (int i=N-1; i>=0; i--) {
17765            ProcessRecord app = mLruProcesses.get(i);
17766            if (!app.killedByAm && app.thread != null) {
17767                app.procStateChanged = false;
17768                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17769
17770                // If we haven't yet assigned the final cached adj
17771                // to the process, do that now.
17772                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17773                    switch (app.curProcState) {
17774                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17775                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17776                            // This process is a cached process holding activities...
17777                            // assign it the next cached value for that type, and then
17778                            // step that cached level.
17779                            app.curRawAdj = curCachedAdj;
17780                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17781                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17782                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17783                                    + ")");
17784                            if (curCachedAdj != nextCachedAdj) {
17785                                stepCached++;
17786                                if (stepCached >= cachedFactor) {
17787                                    stepCached = 0;
17788                                    curCachedAdj = nextCachedAdj;
17789                                    nextCachedAdj += 2;
17790                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17791                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17792                                    }
17793                                }
17794                            }
17795                            break;
17796                        default:
17797                            // For everything else, assign next empty cached process
17798                            // level and bump that up.  Note that this means that
17799                            // long-running services that have dropped down to the
17800                            // cached level will be treated as empty (since their process
17801                            // state is still as a service), which is what we want.
17802                            app.curRawAdj = curEmptyAdj;
17803                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17804                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17805                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17806                                    + ")");
17807                            if (curEmptyAdj != nextEmptyAdj) {
17808                                stepEmpty++;
17809                                if (stepEmpty >= emptyFactor) {
17810                                    stepEmpty = 0;
17811                                    curEmptyAdj = nextEmptyAdj;
17812                                    nextEmptyAdj += 2;
17813                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17814                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17815                                    }
17816                                }
17817                            }
17818                            break;
17819                    }
17820                }
17821
17822                applyOomAdjLocked(app, TOP_APP, true, now);
17823
17824                // Count the number of process types.
17825                switch (app.curProcState) {
17826                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17827                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17828                        mNumCachedHiddenProcs++;
17829                        numCached++;
17830                        if (numCached > cachedProcessLimit) {
17831                            app.kill("cached #" + numCached, true);
17832                        }
17833                        break;
17834                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17835                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17836                                && app.lastActivityTime < oldTime) {
17837                            app.kill("empty for "
17838                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17839                                    / 1000) + "s", true);
17840                        } else {
17841                            numEmpty++;
17842                            if (numEmpty > emptyProcessLimit) {
17843                                app.kill("empty #" + numEmpty, true);
17844                            }
17845                        }
17846                        break;
17847                    default:
17848                        mNumNonCachedProcs++;
17849                        break;
17850                }
17851
17852                if (app.isolated && app.services.size() <= 0) {
17853                    // If this is an isolated process, and there are no
17854                    // services running in it, then the process is no longer
17855                    // needed.  We agressively kill these because we can by
17856                    // definition not re-use the same process again, and it is
17857                    // good to avoid having whatever code was running in them
17858                    // left sitting around after no longer needed.
17859                    app.kill("isolated not needed", true);
17860                }
17861
17862                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17863                        && !app.killedByAm) {
17864                    numTrimming++;
17865                }
17866            }
17867        }
17868
17869        mNumServiceProcs = mNewNumServiceProcs;
17870
17871        // Now determine the memory trimming level of background processes.
17872        // Unfortunately we need to start at the back of the list to do this
17873        // properly.  We only do this if the number of background apps we
17874        // are managing to keep around is less than half the maximum we desire;
17875        // if we are keeping a good number around, we'll let them use whatever
17876        // memory they want.
17877        final int numCachedAndEmpty = numCached + numEmpty;
17878        int memFactor;
17879        if (numCached <= ProcessList.TRIM_CACHED_APPS
17880                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17881            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17882                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17883            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17884                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17885            } else {
17886                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17887            }
17888        } else {
17889            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17890        }
17891        // We always allow the memory level to go up (better).  We only allow it to go
17892        // down if we are in a state where that is allowed, *and* the total number of processes
17893        // has gone down since last time.
17894        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17895                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17896                + " last=" + mLastNumProcesses);
17897        if (memFactor > mLastMemoryLevel) {
17898            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17899                memFactor = mLastMemoryLevel;
17900                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17901            }
17902        }
17903        mLastMemoryLevel = memFactor;
17904        mLastNumProcesses = mLruProcesses.size();
17905        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17906        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17907        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17908            if (mLowRamStartTime == 0) {
17909                mLowRamStartTime = now;
17910            }
17911            int step = 0;
17912            int fgTrimLevel;
17913            switch (memFactor) {
17914                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17915                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17916                    break;
17917                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17918                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17919                    break;
17920                default:
17921                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17922                    break;
17923            }
17924            int factor = numTrimming/3;
17925            int minFactor = 2;
17926            if (mHomeProcess != null) minFactor++;
17927            if (mPreviousProcess != null) minFactor++;
17928            if (factor < minFactor) factor = minFactor;
17929            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17930            for (int i=N-1; i>=0; i--) {
17931                ProcessRecord app = mLruProcesses.get(i);
17932                if (allChanged || app.procStateChanged) {
17933                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17934                    app.procStateChanged = false;
17935                }
17936                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17937                        && !app.killedByAm) {
17938                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17939                        try {
17940                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17941                                    "Trimming memory of " + app.processName
17942                                    + " to " + curLevel);
17943                            app.thread.scheduleTrimMemory(curLevel);
17944                        } catch (RemoteException e) {
17945                        }
17946                        if (false) {
17947                            // For now we won't do this; our memory trimming seems
17948                            // to be good enough at this point that destroying
17949                            // activities causes more harm than good.
17950                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17951                                    && app != mHomeProcess && app != mPreviousProcess) {
17952                                // Need to do this on its own message because the stack may not
17953                                // be in a consistent state at this point.
17954                                // For these apps we will also finish their activities
17955                                // to help them free memory.
17956                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17957                            }
17958                        }
17959                    }
17960                    app.trimMemoryLevel = curLevel;
17961                    step++;
17962                    if (step >= factor) {
17963                        step = 0;
17964                        switch (curLevel) {
17965                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17966                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17967                                break;
17968                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17969                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17970                                break;
17971                        }
17972                    }
17973                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17974                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17975                            && app.thread != null) {
17976                        try {
17977                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17978                                    "Trimming memory of heavy-weight " + app.processName
17979                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17980                            app.thread.scheduleTrimMemory(
17981                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17982                        } catch (RemoteException e) {
17983                        }
17984                    }
17985                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17986                } else {
17987                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17988                            || app.systemNoUi) && app.pendingUiClean) {
17989                        // If this application is now in the background and it
17990                        // had done UI, then give it the special trim level to
17991                        // have it free UI resources.
17992                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17993                        if (app.trimMemoryLevel < level && app.thread != null) {
17994                            try {
17995                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17996                                        "Trimming memory of bg-ui " + app.processName
17997                                        + " to " + level);
17998                                app.thread.scheduleTrimMemory(level);
17999                            } catch (RemoteException e) {
18000                            }
18001                        }
18002                        app.pendingUiClean = false;
18003                    }
18004                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18005                        try {
18006                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18007                                    "Trimming memory of fg " + app.processName
18008                                    + " to " + fgTrimLevel);
18009                            app.thread.scheduleTrimMemory(fgTrimLevel);
18010                        } catch (RemoteException e) {
18011                        }
18012                    }
18013                    app.trimMemoryLevel = fgTrimLevel;
18014                }
18015            }
18016        } else {
18017            if (mLowRamStartTime != 0) {
18018                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18019                mLowRamStartTime = 0;
18020            }
18021            for (int i=N-1; i>=0; i--) {
18022                ProcessRecord app = mLruProcesses.get(i);
18023                if (allChanged || app.procStateChanged) {
18024                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18025                    app.procStateChanged = false;
18026                }
18027                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18028                        || app.systemNoUi) && app.pendingUiClean) {
18029                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18030                            && app.thread != null) {
18031                        try {
18032                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18033                                    "Trimming memory of ui hidden " + app.processName
18034                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18035                            app.thread.scheduleTrimMemory(
18036                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18037                        } catch (RemoteException e) {
18038                        }
18039                    }
18040                    app.pendingUiClean = false;
18041                }
18042                app.trimMemoryLevel = 0;
18043            }
18044        }
18045
18046        if (mAlwaysFinishActivities) {
18047            // Need to do this on its own message because the stack may not
18048            // be in a consistent state at this point.
18049            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18050        }
18051
18052        if (allChanged) {
18053            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18054        }
18055
18056        if (mProcessStats.shouldWriteNowLocked(now)) {
18057            mHandler.post(new Runnable() {
18058                @Override public void run() {
18059                    synchronized (ActivityManagerService.this) {
18060                        mProcessStats.writeStateAsyncLocked();
18061                    }
18062                }
18063            });
18064        }
18065
18066        if (DEBUG_OOM_ADJ) {
18067            if (false) {
18068                RuntimeException here = new RuntimeException("here");
18069                here.fillInStackTrace();
18070                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18071            } else {
18072                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18073            }
18074        }
18075    }
18076
18077    final void trimApplications() {
18078        synchronized (this) {
18079            int i;
18080
18081            // First remove any unused application processes whose package
18082            // has been removed.
18083            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18084                final ProcessRecord app = mRemovedProcesses.get(i);
18085                if (app.activities.size() == 0
18086                        && app.curReceiver == null && app.services.size() == 0) {
18087                    Slog.i(
18088                        TAG, "Exiting empty application process "
18089                        + app.processName + " ("
18090                        + (app.thread != null ? app.thread.asBinder() : null)
18091                        + ")\n");
18092                    if (app.pid > 0 && app.pid != MY_PID) {
18093                        app.kill("empty", false);
18094                    } else {
18095                        try {
18096                            app.thread.scheduleExit();
18097                        } catch (Exception e) {
18098                            // Ignore exceptions.
18099                        }
18100                    }
18101                    cleanUpApplicationRecordLocked(app, false, true, -1);
18102                    mRemovedProcesses.remove(i);
18103
18104                    if (app.persistent) {
18105                        addAppLocked(app.info, false, null /* ABI override */);
18106                    }
18107                }
18108            }
18109
18110            // Now update the oom adj for all processes.
18111            updateOomAdjLocked();
18112        }
18113    }
18114
18115    /** This method sends the specified signal to each of the persistent apps */
18116    public void signalPersistentProcesses(int sig) throws RemoteException {
18117        if (sig != Process.SIGNAL_USR1) {
18118            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18119        }
18120
18121        synchronized (this) {
18122            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18123                    != PackageManager.PERMISSION_GRANTED) {
18124                throw new SecurityException("Requires permission "
18125                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18126            }
18127
18128            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18129                ProcessRecord r = mLruProcesses.get(i);
18130                if (r.thread != null && r.persistent) {
18131                    Process.sendSignal(r.pid, sig);
18132                }
18133            }
18134        }
18135    }
18136
18137    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18138        if (proc == null || proc == mProfileProc) {
18139            proc = mProfileProc;
18140            profileType = mProfileType;
18141            clearProfilerLocked();
18142        }
18143        if (proc == null) {
18144            return;
18145        }
18146        try {
18147            proc.thread.profilerControl(false, null, profileType);
18148        } catch (RemoteException e) {
18149            throw new IllegalStateException("Process disappeared");
18150        }
18151    }
18152
18153    private void clearProfilerLocked() {
18154        if (mProfileFd != null) {
18155            try {
18156                mProfileFd.close();
18157            } catch (IOException e) {
18158            }
18159        }
18160        mProfileApp = null;
18161        mProfileProc = null;
18162        mProfileFile = null;
18163        mProfileType = 0;
18164        mAutoStopProfiler = false;
18165        mSamplingInterval = 0;
18166    }
18167
18168    public boolean profileControl(String process, int userId, boolean start,
18169            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18170
18171        try {
18172            synchronized (this) {
18173                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18174                // its own permission.
18175                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18176                        != PackageManager.PERMISSION_GRANTED) {
18177                    throw new SecurityException("Requires permission "
18178                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18179                }
18180
18181                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18182                    throw new IllegalArgumentException("null profile info or fd");
18183                }
18184
18185                ProcessRecord proc = null;
18186                if (process != null) {
18187                    proc = findProcessLocked(process, userId, "profileControl");
18188                }
18189
18190                if (start && (proc == null || proc.thread == null)) {
18191                    throw new IllegalArgumentException("Unknown process: " + process);
18192                }
18193
18194                if (start) {
18195                    stopProfilerLocked(null, 0);
18196                    setProfileApp(proc.info, proc.processName, profilerInfo);
18197                    mProfileProc = proc;
18198                    mProfileType = profileType;
18199                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18200                    try {
18201                        fd = fd.dup();
18202                    } catch (IOException e) {
18203                        fd = null;
18204                    }
18205                    profilerInfo.profileFd = fd;
18206                    proc.thread.profilerControl(start, profilerInfo, profileType);
18207                    fd = null;
18208                    mProfileFd = null;
18209                } else {
18210                    stopProfilerLocked(proc, profileType);
18211                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18212                        try {
18213                            profilerInfo.profileFd.close();
18214                        } catch (IOException e) {
18215                        }
18216                    }
18217                }
18218
18219                return true;
18220            }
18221        } catch (RemoteException e) {
18222            throw new IllegalStateException("Process disappeared");
18223        } finally {
18224            if (profilerInfo != null && profilerInfo.profileFd != null) {
18225                try {
18226                    profilerInfo.profileFd.close();
18227                } catch (IOException e) {
18228                }
18229            }
18230        }
18231    }
18232
18233    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18234        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18235                userId, true, ALLOW_FULL_ONLY, callName, null);
18236        ProcessRecord proc = null;
18237        try {
18238            int pid = Integer.parseInt(process);
18239            synchronized (mPidsSelfLocked) {
18240                proc = mPidsSelfLocked.get(pid);
18241            }
18242        } catch (NumberFormatException e) {
18243        }
18244
18245        if (proc == null) {
18246            ArrayMap<String, SparseArray<ProcessRecord>> all
18247                    = mProcessNames.getMap();
18248            SparseArray<ProcessRecord> procs = all.get(process);
18249            if (procs != null && procs.size() > 0) {
18250                proc = procs.valueAt(0);
18251                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18252                    for (int i=1; i<procs.size(); i++) {
18253                        ProcessRecord thisProc = procs.valueAt(i);
18254                        if (thisProc.userId == userId) {
18255                            proc = thisProc;
18256                            break;
18257                        }
18258                    }
18259                }
18260            }
18261        }
18262
18263        return proc;
18264    }
18265
18266    public boolean dumpHeap(String process, int userId, boolean managed,
18267            String path, ParcelFileDescriptor fd) throws RemoteException {
18268
18269        try {
18270            synchronized (this) {
18271                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18272                // its own permission (same as profileControl).
18273                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18274                        != PackageManager.PERMISSION_GRANTED) {
18275                    throw new SecurityException("Requires permission "
18276                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18277                }
18278
18279                if (fd == null) {
18280                    throw new IllegalArgumentException("null fd");
18281                }
18282
18283                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18284                if (proc == null || proc.thread == null) {
18285                    throw new IllegalArgumentException("Unknown process: " + process);
18286                }
18287
18288                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18289                if (!isDebuggable) {
18290                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18291                        throw new SecurityException("Process not debuggable: " + proc);
18292                    }
18293                }
18294
18295                proc.thread.dumpHeap(managed, path, fd);
18296                fd = null;
18297                return true;
18298            }
18299        } catch (RemoteException e) {
18300            throw new IllegalStateException("Process disappeared");
18301        } finally {
18302            if (fd != null) {
18303                try {
18304                    fd.close();
18305                } catch (IOException e) {
18306                }
18307            }
18308        }
18309    }
18310
18311    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18312    public void monitor() {
18313        synchronized (this) { }
18314    }
18315
18316    void onCoreSettingsChange(Bundle settings) {
18317        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18318            ProcessRecord processRecord = mLruProcesses.get(i);
18319            try {
18320                if (processRecord.thread != null) {
18321                    processRecord.thread.setCoreSettings(settings);
18322                }
18323            } catch (RemoteException re) {
18324                /* ignore */
18325            }
18326        }
18327    }
18328
18329    // Multi-user methods
18330
18331    /**
18332     * Start user, if its not already running, but don't bring it to foreground.
18333     */
18334    @Override
18335    public boolean startUserInBackground(final int userId) {
18336        return startUser(userId, /* foreground */ false);
18337    }
18338
18339    /**
18340     * Start user, if its not already running, and bring it to foreground.
18341     */
18342    boolean startUserInForeground(final int userId, Dialog dlg) {
18343        boolean result = startUser(userId, /* foreground */ true);
18344        dlg.dismiss();
18345        return result;
18346    }
18347
18348    /**
18349     * Refreshes the list of users related to the current user when either a
18350     * user switch happens or when a new related user is started in the
18351     * background.
18352     */
18353    private void updateCurrentProfileIdsLocked() {
18354        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18355                mCurrentUserId, false /* enabledOnly */);
18356        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18357        for (int i = 0; i < currentProfileIds.length; i++) {
18358            currentProfileIds[i] = profiles.get(i).id;
18359        }
18360        mCurrentProfileIds = currentProfileIds;
18361
18362        synchronized (mUserProfileGroupIdsSelfLocked) {
18363            mUserProfileGroupIdsSelfLocked.clear();
18364            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18365            for (int i = 0; i < users.size(); i++) {
18366                UserInfo user = users.get(i);
18367                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18368                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18369                }
18370            }
18371        }
18372    }
18373
18374    private Set<Integer> getProfileIdsLocked(int userId) {
18375        Set<Integer> userIds = new HashSet<Integer>();
18376        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18377                userId, false /* enabledOnly */);
18378        for (UserInfo user : profiles) {
18379            userIds.add(Integer.valueOf(user.id));
18380        }
18381        return userIds;
18382    }
18383
18384    @Override
18385    public boolean switchUser(final int userId) {
18386        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18387        String userName;
18388        synchronized (this) {
18389            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18390            if (userInfo == null) {
18391                Slog.w(TAG, "No user info for user #" + userId);
18392                return false;
18393            }
18394            if (userInfo.isManagedProfile()) {
18395                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18396                return false;
18397            }
18398            userName = userInfo.name;
18399            mTargetUserId = userId;
18400        }
18401        mHandler.removeMessages(START_USER_SWITCH_MSG);
18402        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18403        return true;
18404    }
18405
18406    private void showUserSwitchDialog(int userId, String userName) {
18407        // The dialog will show and then initiate the user switch by calling startUserInForeground
18408        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18409                true /* above system */);
18410        d.show();
18411    }
18412
18413    private boolean startUser(final int userId, final boolean foreground) {
18414        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18415                != PackageManager.PERMISSION_GRANTED) {
18416            String msg = "Permission Denial: switchUser() from pid="
18417                    + Binder.getCallingPid()
18418                    + ", uid=" + Binder.getCallingUid()
18419                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18420            Slog.w(TAG, msg);
18421            throw new SecurityException(msg);
18422        }
18423
18424        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18425
18426        final long ident = Binder.clearCallingIdentity();
18427        try {
18428            synchronized (this) {
18429                final int oldUserId = mCurrentUserId;
18430                if (oldUserId == userId) {
18431                    return true;
18432                }
18433
18434                mStackSupervisor.setLockTaskModeLocked(null, false, "startUser");
18435
18436                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18437                if (userInfo == null) {
18438                    Slog.w(TAG, "No user info for user #" + userId);
18439                    return false;
18440                }
18441                if (foreground && userInfo.isManagedProfile()) {
18442                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18443                    return false;
18444                }
18445
18446                if (foreground) {
18447                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18448                            R.anim.screen_user_enter);
18449                }
18450
18451                boolean needStart = false;
18452
18453                // If the user we are switching to is not currently started, then
18454                // we need to start it now.
18455                if (mStartedUsers.get(userId) == null) {
18456                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18457                    updateStartedUserArrayLocked();
18458                    needStart = true;
18459                }
18460
18461                final Integer userIdInt = Integer.valueOf(userId);
18462                mUserLru.remove(userIdInt);
18463                mUserLru.add(userIdInt);
18464
18465                if (foreground) {
18466                    mCurrentUserId = userId;
18467                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18468                    updateCurrentProfileIdsLocked();
18469                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18470                    // Once the internal notion of the active user has switched, we lock the device
18471                    // with the option to show the user switcher on the keyguard.
18472                    mWindowManager.lockNow(null);
18473                } else {
18474                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18475                    updateCurrentProfileIdsLocked();
18476                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18477                    mUserLru.remove(currentUserIdInt);
18478                    mUserLru.add(currentUserIdInt);
18479                }
18480
18481                final UserStartedState uss = mStartedUsers.get(userId);
18482
18483                // Make sure user is in the started state.  If it is currently
18484                // stopping, we need to knock that off.
18485                if (uss.mState == UserStartedState.STATE_STOPPING) {
18486                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18487                    // so we can just fairly silently bring the user back from
18488                    // the almost-dead.
18489                    uss.mState = UserStartedState.STATE_RUNNING;
18490                    updateStartedUserArrayLocked();
18491                    needStart = true;
18492                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18493                    // This means ACTION_SHUTDOWN has been sent, so we will
18494                    // need to treat this as a new boot of the user.
18495                    uss.mState = UserStartedState.STATE_BOOTING;
18496                    updateStartedUserArrayLocked();
18497                    needStart = true;
18498                }
18499
18500                if (uss.mState == UserStartedState.STATE_BOOTING) {
18501                    // Booting up a new user, need to tell system services about it.
18502                    // Note that this is on the same handler as scheduling of broadcasts,
18503                    // which is important because it needs to go first.
18504                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18505                }
18506
18507                if (foreground) {
18508                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18509                            oldUserId));
18510                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18511                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18512                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18513                            oldUserId, userId, uss));
18514                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18515                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18516                }
18517
18518                if (needStart) {
18519                    // Send USER_STARTED broadcast
18520                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18521                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18522                            | Intent.FLAG_RECEIVER_FOREGROUND);
18523                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18524                    broadcastIntentLocked(null, null, intent,
18525                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18526                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18527                }
18528
18529                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18530                    if (userId != UserHandle.USER_OWNER) {
18531                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18532                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18533                        broadcastIntentLocked(null, null, intent, null,
18534                                new IIntentReceiver.Stub() {
18535                                    public void performReceive(Intent intent, int resultCode,
18536                                            String data, Bundle extras, boolean ordered,
18537                                            boolean sticky, int sendingUser) {
18538                                        onUserInitialized(uss, foreground, oldUserId, userId);
18539                                    }
18540                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18541                                true, false, MY_PID, Process.SYSTEM_UID,
18542                                userId);
18543                        uss.initializing = true;
18544                    } else {
18545                        getUserManagerLocked().makeInitialized(userInfo.id);
18546                    }
18547                }
18548
18549                if (foreground) {
18550                    if (!uss.initializing) {
18551                        moveUserToForeground(uss, oldUserId, userId);
18552                    }
18553                } else {
18554                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18555                }
18556
18557                if (needStart) {
18558                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18559                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18560                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18561                    broadcastIntentLocked(null, null, intent,
18562                            null, new IIntentReceiver.Stub() {
18563                                @Override
18564                                public void performReceive(Intent intent, int resultCode, String data,
18565                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18566                                        throws RemoteException {
18567                                }
18568                            }, 0, null, null,
18569                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18570                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18571                }
18572            }
18573        } finally {
18574            Binder.restoreCallingIdentity(ident);
18575        }
18576
18577        return true;
18578    }
18579
18580    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18581        long ident = Binder.clearCallingIdentity();
18582        try {
18583            Intent intent;
18584            if (oldUserId >= 0) {
18585                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18586                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18587                int count = profiles.size();
18588                for (int i = 0; i < count; i++) {
18589                    int profileUserId = profiles.get(i).id;
18590                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18591                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18592                            | Intent.FLAG_RECEIVER_FOREGROUND);
18593                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18594                    broadcastIntentLocked(null, null, intent,
18595                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18596                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18597                }
18598            }
18599            if (newUserId >= 0) {
18600                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18601                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18602                int count = profiles.size();
18603                for (int i = 0; i < count; i++) {
18604                    int profileUserId = profiles.get(i).id;
18605                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18606                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18607                            | Intent.FLAG_RECEIVER_FOREGROUND);
18608                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18609                    broadcastIntentLocked(null, null, intent,
18610                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18611                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18612                }
18613                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18614                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18615                        | Intent.FLAG_RECEIVER_FOREGROUND);
18616                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18617                broadcastIntentLocked(null, null, intent,
18618                        null, null, 0, null, null,
18619                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18620                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18621            }
18622        } finally {
18623            Binder.restoreCallingIdentity(ident);
18624        }
18625    }
18626
18627    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18628            final int newUserId) {
18629        final int N = mUserSwitchObservers.beginBroadcast();
18630        if (N > 0) {
18631            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18632                int mCount = 0;
18633                @Override
18634                public void sendResult(Bundle data) throws RemoteException {
18635                    synchronized (ActivityManagerService.this) {
18636                        if (mCurUserSwitchCallback == this) {
18637                            mCount++;
18638                            if (mCount == N) {
18639                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18640                            }
18641                        }
18642                    }
18643                }
18644            };
18645            synchronized (this) {
18646                uss.switching = true;
18647                mCurUserSwitchCallback = callback;
18648            }
18649            for (int i=0; i<N; i++) {
18650                try {
18651                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18652                            newUserId, callback);
18653                } catch (RemoteException e) {
18654                }
18655            }
18656        } else {
18657            synchronized (this) {
18658                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18659            }
18660        }
18661        mUserSwitchObservers.finishBroadcast();
18662    }
18663
18664    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18665        synchronized (this) {
18666            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18667            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18668        }
18669    }
18670
18671    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18672        mCurUserSwitchCallback = null;
18673        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18674        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18675                oldUserId, newUserId, uss));
18676    }
18677
18678    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18679        synchronized (this) {
18680            if (foreground) {
18681                moveUserToForeground(uss, oldUserId, newUserId);
18682            }
18683        }
18684
18685        completeSwitchAndInitalize(uss, newUserId, true, false);
18686    }
18687
18688    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18689        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18690        if (homeInFront) {
18691            startHomeActivityLocked(newUserId, "moveUserToFroreground");
18692        } else {
18693            mStackSupervisor.resumeTopActivitiesLocked();
18694        }
18695        EventLogTags.writeAmSwitchUser(newUserId);
18696        getUserManagerLocked().userForeground(newUserId);
18697        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18698    }
18699
18700    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18701        completeSwitchAndInitalize(uss, newUserId, false, true);
18702    }
18703
18704    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18705            boolean clearInitializing, boolean clearSwitching) {
18706        boolean unfrozen = false;
18707        synchronized (this) {
18708            if (clearInitializing) {
18709                uss.initializing = false;
18710                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18711            }
18712            if (clearSwitching) {
18713                uss.switching = false;
18714            }
18715            if (!uss.switching && !uss.initializing) {
18716                mWindowManager.stopFreezingScreen();
18717                unfrozen = true;
18718            }
18719        }
18720        if (unfrozen) {
18721            final int N = mUserSwitchObservers.beginBroadcast();
18722            for (int i=0; i<N; i++) {
18723                try {
18724                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18725                } catch (RemoteException e) {
18726                }
18727            }
18728            mUserSwitchObservers.finishBroadcast();
18729        }
18730        stopGuestUserIfBackground();
18731    }
18732
18733    /**
18734     * Stops the guest user if it has gone to the background.
18735     */
18736    private void stopGuestUserIfBackground() {
18737        synchronized (this) {
18738            final int num = mUserLru.size();
18739            for (int i = 0; i < num; i++) {
18740                Integer oldUserId = mUserLru.get(i);
18741                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18742                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
18743                        || oldUss.mState == UserStartedState.STATE_STOPPING
18744                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18745                    continue;
18746                }
18747                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
18748                if (userInfo.isGuest()) {
18749                    // This is a user to be stopped.
18750                    stopUserLocked(oldUserId, null);
18751                    break;
18752                }
18753            }
18754        }
18755    }
18756
18757    void scheduleStartProfilesLocked() {
18758        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18759            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18760                    DateUtils.SECOND_IN_MILLIS);
18761        }
18762    }
18763
18764    void startProfilesLocked() {
18765        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18766        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18767                mCurrentUserId, false /* enabledOnly */);
18768        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18769        for (UserInfo user : profiles) {
18770            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18771                    && user.id != mCurrentUserId) {
18772                toStart.add(user);
18773            }
18774        }
18775        final int n = toStart.size();
18776        int i = 0;
18777        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18778            startUserInBackground(toStart.get(i).id);
18779        }
18780        if (i < n) {
18781            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18782        }
18783    }
18784
18785    void finishUserBoot(UserStartedState uss) {
18786        synchronized (this) {
18787            if (uss.mState == UserStartedState.STATE_BOOTING
18788                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18789                uss.mState = UserStartedState.STATE_RUNNING;
18790                final int userId = uss.mHandle.getIdentifier();
18791                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18792                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18793                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18794                broadcastIntentLocked(null, null, intent,
18795                        null, null, 0, null, null,
18796                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18797                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18798            }
18799        }
18800    }
18801
18802    void finishUserSwitch(UserStartedState uss) {
18803        synchronized (this) {
18804            finishUserBoot(uss);
18805
18806            startProfilesLocked();
18807
18808            int num = mUserLru.size();
18809            int i = 0;
18810            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18811                Integer oldUserId = mUserLru.get(i);
18812                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18813                if (oldUss == null) {
18814                    // Shouldn't happen, but be sane if it does.
18815                    mUserLru.remove(i);
18816                    num--;
18817                    continue;
18818                }
18819                if (oldUss.mState == UserStartedState.STATE_STOPPING
18820                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18821                    // This user is already stopping, doesn't count.
18822                    num--;
18823                    i++;
18824                    continue;
18825                }
18826                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18827                    // Owner and current can't be stopped, but count as running.
18828                    i++;
18829                    continue;
18830                }
18831                // This is a user to be stopped.
18832                stopUserLocked(oldUserId, null);
18833                num--;
18834                i++;
18835            }
18836        }
18837    }
18838
18839    @Override
18840    public int stopUser(final int userId, final IStopUserCallback callback) {
18841        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18842                != PackageManager.PERMISSION_GRANTED) {
18843            String msg = "Permission Denial: switchUser() from pid="
18844                    + Binder.getCallingPid()
18845                    + ", uid=" + Binder.getCallingUid()
18846                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18847            Slog.w(TAG, msg);
18848            throw new SecurityException(msg);
18849        }
18850        if (userId <= 0) {
18851            throw new IllegalArgumentException("Can't stop primary user " + userId);
18852        }
18853        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18854        synchronized (this) {
18855            return stopUserLocked(userId, callback);
18856        }
18857    }
18858
18859    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18860        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18861        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18862            return ActivityManager.USER_OP_IS_CURRENT;
18863        }
18864
18865        final UserStartedState uss = mStartedUsers.get(userId);
18866        if (uss == null) {
18867            // User is not started, nothing to do...  but we do need to
18868            // callback if requested.
18869            if (callback != null) {
18870                mHandler.post(new Runnable() {
18871                    @Override
18872                    public void run() {
18873                        try {
18874                            callback.userStopped(userId);
18875                        } catch (RemoteException e) {
18876                        }
18877                    }
18878                });
18879            }
18880            return ActivityManager.USER_OP_SUCCESS;
18881        }
18882
18883        if (callback != null) {
18884            uss.mStopCallbacks.add(callback);
18885        }
18886
18887        if (uss.mState != UserStartedState.STATE_STOPPING
18888                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18889            uss.mState = UserStartedState.STATE_STOPPING;
18890            updateStartedUserArrayLocked();
18891
18892            long ident = Binder.clearCallingIdentity();
18893            try {
18894                // We are going to broadcast ACTION_USER_STOPPING and then
18895                // once that is done send a final ACTION_SHUTDOWN and then
18896                // stop the user.
18897                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18898                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18899                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18900                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18901                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18902                // This is the result receiver for the final shutdown broadcast.
18903                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18904                    @Override
18905                    public void performReceive(Intent intent, int resultCode, String data,
18906                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18907                        finishUserStop(uss);
18908                    }
18909                };
18910                // This is the result receiver for the initial stopping broadcast.
18911                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18912                    @Override
18913                    public void performReceive(Intent intent, int resultCode, String data,
18914                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18915                        // On to the next.
18916                        synchronized (ActivityManagerService.this) {
18917                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18918                                // Whoops, we are being started back up.  Abort, abort!
18919                                return;
18920                            }
18921                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18922                        }
18923                        mBatteryStatsService.noteEvent(
18924                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18925                                Integer.toString(userId), userId);
18926                        mSystemServiceManager.stopUser(userId);
18927                        broadcastIntentLocked(null, null, shutdownIntent,
18928                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18929                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18930                    }
18931                };
18932                // Kick things off.
18933                broadcastIntentLocked(null, null, stoppingIntent,
18934                        null, stoppingReceiver, 0, null, null,
18935                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18936                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18937            } finally {
18938                Binder.restoreCallingIdentity(ident);
18939            }
18940        }
18941
18942        return ActivityManager.USER_OP_SUCCESS;
18943    }
18944
18945    void finishUserStop(UserStartedState uss) {
18946        final int userId = uss.mHandle.getIdentifier();
18947        boolean stopped;
18948        ArrayList<IStopUserCallback> callbacks;
18949        synchronized (this) {
18950            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18951            if (mStartedUsers.get(userId) != uss) {
18952                stopped = false;
18953            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18954                stopped = false;
18955            } else {
18956                stopped = true;
18957                // User can no longer run.
18958                mStartedUsers.remove(userId);
18959                mUserLru.remove(Integer.valueOf(userId));
18960                updateStartedUserArrayLocked();
18961
18962                // Clean up all state and processes associated with the user.
18963                // Kill all the processes for the user.
18964                forceStopUserLocked(userId, "finish user");
18965            }
18966
18967            // Explicitly remove the old information in mRecentTasks.
18968            mRecentTasks.removeTasksForUserLocked(userId);
18969        }
18970
18971        for (int i=0; i<callbacks.size(); i++) {
18972            try {
18973                if (stopped) callbacks.get(i).userStopped(userId);
18974                else callbacks.get(i).userStopAborted(userId);
18975            } catch (RemoteException e) {
18976            }
18977        }
18978
18979        if (stopped) {
18980            mSystemServiceManager.cleanupUser(userId);
18981            synchronized (this) {
18982                mStackSupervisor.removeUserLocked(userId);
18983            }
18984        }
18985    }
18986
18987    @Override
18988    public UserInfo getCurrentUser() {
18989        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18990                != PackageManager.PERMISSION_GRANTED) && (
18991                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18992                != PackageManager.PERMISSION_GRANTED)) {
18993            String msg = "Permission Denial: getCurrentUser() from pid="
18994                    + Binder.getCallingPid()
18995                    + ", uid=" + Binder.getCallingUid()
18996                    + " requires " + INTERACT_ACROSS_USERS;
18997            Slog.w(TAG, msg);
18998            throw new SecurityException(msg);
18999        }
19000        synchronized (this) {
19001            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19002            return getUserManagerLocked().getUserInfo(userId);
19003        }
19004    }
19005
19006    int getCurrentUserIdLocked() {
19007        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19008    }
19009
19010    @Override
19011    public boolean isUserRunning(int userId, boolean orStopped) {
19012        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19013                != PackageManager.PERMISSION_GRANTED) {
19014            String msg = "Permission Denial: isUserRunning() from pid="
19015                    + Binder.getCallingPid()
19016                    + ", uid=" + Binder.getCallingUid()
19017                    + " requires " + INTERACT_ACROSS_USERS;
19018            Slog.w(TAG, msg);
19019            throw new SecurityException(msg);
19020        }
19021        synchronized (this) {
19022            return isUserRunningLocked(userId, orStopped);
19023        }
19024    }
19025
19026    boolean isUserRunningLocked(int userId, boolean orStopped) {
19027        UserStartedState state = mStartedUsers.get(userId);
19028        if (state == null) {
19029            return false;
19030        }
19031        if (orStopped) {
19032            return true;
19033        }
19034        return state.mState != UserStartedState.STATE_STOPPING
19035                && state.mState != UserStartedState.STATE_SHUTDOWN;
19036    }
19037
19038    @Override
19039    public int[] getRunningUserIds() {
19040        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19041                != PackageManager.PERMISSION_GRANTED) {
19042            String msg = "Permission Denial: isUserRunning() from pid="
19043                    + Binder.getCallingPid()
19044                    + ", uid=" + Binder.getCallingUid()
19045                    + " requires " + INTERACT_ACROSS_USERS;
19046            Slog.w(TAG, msg);
19047            throw new SecurityException(msg);
19048        }
19049        synchronized (this) {
19050            return mStartedUserArray;
19051        }
19052    }
19053
19054    private void updateStartedUserArrayLocked() {
19055        int num = 0;
19056        for (int i=0; i<mStartedUsers.size();  i++) {
19057            UserStartedState uss = mStartedUsers.valueAt(i);
19058            // This list does not include stopping users.
19059            if (uss.mState != UserStartedState.STATE_STOPPING
19060                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19061                num++;
19062            }
19063        }
19064        mStartedUserArray = new int[num];
19065        num = 0;
19066        for (int i=0; i<mStartedUsers.size();  i++) {
19067            UserStartedState uss = mStartedUsers.valueAt(i);
19068            if (uss.mState != UserStartedState.STATE_STOPPING
19069                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19070                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19071                num++;
19072            }
19073        }
19074    }
19075
19076    @Override
19077    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19078        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19079                != PackageManager.PERMISSION_GRANTED) {
19080            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19081                    + Binder.getCallingPid()
19082                    + ", uid=" + Binder.getCallingUid()
19083                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19084            Slog.w(TAG, msg);
19085            throw new SecurityException(msg);
19086        }
19087
19088        mUserSwitchObservers.register(observer);
19089    }
19090
19091    @Override
19092    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19093        mUserSwitchObservers.unregister(observer);
19094    }
19095
19096    private boolean userExists(int userId) {
19097        if (userId == 0) {
19098            return true;
19099        }
19100        UserManagerService ums = getUserManagerLocked();
19101        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19102    }
19103
19104    int[] getUsersLocked() {
19105        UserManagerService ums = getUserManagerLocked();
19106        return ums != null ? ums.getUserIds() : new int[] { 0 };
19107    }
19108
19109    UserManagerService getUserManagerLocked() {
19110        if (mUserManager == null) {
19111            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19112            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19113        }
19114        return mUserManager;
19115    }
19116
19117    private int applyUserId(int uid, int userId) {
19118        return UserHandle.getUid(userId, uid);
19119    }
19120
19121    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19122        if (info == null) return null;
19123        ApplicationInfo newInfo = new ApplicationInfo(info);
19124        newInfo.uid = applyUserId(info.uid, userId);
19125        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19126                + info.packageName;
19127        return newInfo;
19128    }
19129
19130    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19131        if (aInfo == null
19132                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19133            return aInfo;
19134        }
19135
19136        ActivityInfo info = new ActivityInfo(aInfo);
19137        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19138        return info;
19139    }
19140
19141    private final class LocalService extends ActivityManagerInternal {
19142        @Override
19143        public void onWakefulnessChanged(int wakefulness) {
19144            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19145        }
19146
19147        @Override
19148        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19149                String processName, String abiOverride, int uid, Runnable crashHandler) {
19150            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19151                    processName, abiOverride, uid, crashHandler);
19152        }
19153    }
19154
19155    /**
19156     * An implementation of IAppTask, that allows an app to manage its own tasks via
19157     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19158     * only the process that calls getAppTasks() can call the AppTask methods.
19159     */
19160    class AppTaskImpl extends IAppTask.Stub {
19161        private int mTaskId;
19162        private int mCallingUid;
19163
19164        public AppTaskImpl(int taskId, int callingUid) {
19165            mTaskId = taskId;
19166            mCallingUid = callingUid;
19167        }
19168
19169        private void checkCaller() {
19170            if (mCallingUid != Binder.getCallingUid()) {
19171                throw new SecurityException("Caller " + mCallingUid
19172                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19173            }
19174        }
19175
19176        @Override
19177        public void finishAndRemoveTask() {
19178            checkCaller();
19179
19180            synchronized (ActivityManagerService.this) {
19181                long origId = Binder.clearCallingIdentity();
19182                try {
19183                    if (!removeTaskByIdLocked(mTaskId, false)) {
19184                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19185                    }
19186                } finally {
19187                    Binder.restoreCallingIdentity(origId);
19188                }
19189            }
19190        }
19191
19192        @Override
19193        public ActivityManager.RecentTaskInfo getTaskInfo() {
19194            checkCaller();
19195
19196            synchronized (ActivityManagerService.this) {
19197                long origId = Binder.clearCallingIdentity();
19198                try {
19199                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
19200                    if (tr == null) {
19201                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19202                    }
19203                    return createRecentTaskInfoFromTaskRecord(tr);
19204                } finally {
19205                    Binder.restoreCallingIdentity(origId);
19206                }
19207            }
19208        }
19209
19210        @Override
19211        public void moveToFront() {
19212            checkCaller();
19213            // Will bring task to front if it already has a root activity.
19214            startActivityFromRecentsInner(mTaskId, null);
19215        }
19216
19217        @Override
19218        public int startActivity(IBinder whoThread, String callingPackage,
19219                Intent intent, String resolvedType, Bundle options) {
19220            checkCaller();
19221
19222            int callingUser = UserHandle.getCallingUserId();
19223            TaskRecord tr;
19224            IApplicationThread appThread;
19225            synchronized (ActivityManagerService.this) {
19226                tr = mRecentTasks.taskForIdLocked(mTaskId);
19227                if (tr == null) {
19228                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19229                }
19230                appThread = ApplicationThreadNative.asInterface(whoThread);
19231                if (appThread == null) {
19232                    throw new IllegalArgumentException("Bad app thread " + appThread);
19233                }
19234            }
19235            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19236                    resolvedType, null, null, null, null, 0, 0, null, null,
19237                    null, options, callingUser, null, tr);
19238        }
19239
19240        @Override
19241        public void setExcludeFromRecents(boolean exclude) {
19242            checkCaller();
19243
19244            synchronized (ActivityManagerService.this) {
19245                long origId = Binder.clearCallingIdentity();
19246                try {
19247                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
19248                    if (tr == null) {
19249                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19250                    }
19251                    Intent intent = tr.getBaseIntent();
19252                    if (exclude) {
19253                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19254                    } else {
19255                        intent.setFlags(intent.getFlags()
19256                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19257                    }
19258                } finally {
19259                    Binder.restoreCallingIdentity(origId);
19260                }
19261            }
19262        }
19263    }
19264}
19265