ActivityManagerService.java revision 2cffc7dafd390f6fe24a9fbb3ef3bc8226f5b385
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;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.os.storage.IMountService;
52import android.os.storage.StorageManager;
53import android.service.voice.IVoiceInteractionSession;
54import android.util.ArrayMap;
55import android.util.ArraySet;
56import android.util.SparseIntArray;
57
58import com.android.internal.R;
59import com.android.internal.annotations.GuardedBy;
60import com.android.internal.app.IAppOpsService;
61import com.android.internal.app.IVoiceInteractor;
62import com.android.internal.app.ProcessMap;
63import com.android.internal.app.ProcessStats;
64import com.android.internal.content.PackageMonitor;
65import com.android.internal.os.BackgroundThread;
66import com.android.internal.os.BatteryStatsImpl;
67import com.android.internal.os.ProcessCpuTracker;
68import com.android.internal.os.TransferPipe;
69import com.android.internal.os.Zygote;
70import com.android.internal.util.FastPrintWriter;
71import com.android.internal.util.FastXmlSerializer;
72import com.android.internal.util.MemInfoReader;
73import com.android.internal.util.Preconditions;
74import com.android.server.AppOpsService;
75import com.android.server.AttributeCache;
76import com.android.server.IntentResolver;
77import com.android.server.LocalServices;
78import com.android.server.ServiceThread;
79import com.android.server.SystemService;
80import com.android.server.SystemServiceManager;
81import com.android.server.Watchdog;
82import com.android.server.am.ActivityStack.ActivityState;
83import com.android.server.firewall.IntentFirewall;
84import com.android.server.pm.Installer;
85import com.android.server.pm.UserManagerService;
86import com.android.server.statusbar.StatusBarManagerInternal;
87import com.android.server.wm.AppTransition;
88import com.android.server.wm.WindowManagerService;
89import com.google.android.collect.Lists;
90import com.google.android.collect.Maps;
91
92import libcore.io.IoUtils;
93
94import org.xmlpull.v1.XmlPullParser;
95import org.xmlpull.v1.XmlPullParserException;
96import org.xmlpull.v1.XmlSerializer;
97
98import android.app.Activity;
99import android.app.ActivityManager;
100import android.app.ActivityManager.RunningTaskInfo;
101import android.app.ActivityManager.StackInfo;
102import android.app.ActivityManagerInternal;
103import android.app.ActivityManagerNative;
104import android.app.ActivityOptions;
105import android.app.ActivityThread;
106import android.app.AlertDialog;
107import android.app.AppGlobals;
108import android.app.ApplicationErrorReport;
109import android.app.Dialog;
110import android.app.IActivityController;
111import android.app.IApplicationThread;
112import android.app.IInstrumentationWatcher;
113import android.app.INotificationManager;
114import android.app.IProcessObserver;
115import android.app.IServiceConnection;
116import android.app.IStopUserCallback;
117import android.app.IUiAutomationConnection;
118import android.app.IUserSwitchObserver;
119import android.app.Instrumentation;
120import android.app.Notification;
121import android.app.NotificationManager;
122import android.app.PendingIntent;
123import android.app.backup.IBackupManager;
124import android.content.ActivityNotFoundException;
125import android.content.BroadcastReceiver;
126import android.content.ClipData;
127import android.content.ComponentCallbacks2;
128import android.content.ComponentName;
129import android.content.ContentProvider;
130import android.content.ContentResolver;
131import android.content.Context;
132import android.content.DialogInterface;
133import android.content.IContentProvider;
134import android.content.IIntentReceiver;
135import android.content.IIntentSender;
136import android.content.Intent;
137import android.content.IntentFilter;
138import android.content.IntentSender;
139import android.content.pm.ActivityInfo;
140import android.content.pm.ApplicationInfo;
141import android.content.pm.ConfigurationInfo;
142import android.content.pm.IPackageDataObserver;
143import android.content.pm.IPackageManager;
144import android.content.pm.InstrumentationInfo;
145import android.content.pm.PackageInfo;
146import android.content.pm.PackageManager;
147import android.content.pm.ParceledListSlice;
148import android.content.pm.UserInfo;
149import android.content.pm.PackageManager.NameNotFoundException;
150import android.content.pm.PathPermission;
151import android.content.pm.ProviderInfo;
152import android.content.pm.ResolveInfo;
153import android.content.pm.ServiceInfo;
154import android.content.res.CompatibilityInfo;
155import android.content.res.Configuration;
156import android.net.Proxy;
157import android.net.ProxyInfo;
158import android.net.Uri;
159import android.os.Binder;
160import android.os.Build;
161import android.os.Bundle;
162import android.os.Debug;
163import android.os.DropBoxManager;
164import android.os.Environment;
165import android.os.FactoryTest;
166import android.os.FileObserver;
167import android.os.FileUtils;
168import android.os.Handler;
169import android.os.IBinder;
170import android.os.IPermissionController;
171import android.os.IRemoteCallback;
172import android.os.IUserManager;
173import android.os.Looper;
174import android.os.Message;
175import android.os.Parcel;
176import android.os.ParcelFileDescriptor;
177import android.os.Process;
178import android.os.RemoteCallbackList;
179import android.os.RemoteException;
180import android.os.SELinux;
181import android.os.ServiceManager;
182import android.os.StrictMode;
183import android.os.SystemClock;
184import android.os.SystemProperties;
185import android.os.UpdateLock;
186import android.os.UserHandle;
187import android.os.UserManager;
188import android.provider.Settings;
189import android.text.format.DateUtils;
190import android.text.format.Time;
191import android.util.AtomicFile;
192import android.util.EventLog;
193import android.util.Log;
194import android.util.Pair;
195import android.util.PrintWriterPrinter;
196import android.util.Slog;
197import android.util.SparseArray;
198import android.util.TimeUtils;
199import android.util.Xml;
200import android.view.Gravity;
201import android.view.LayoutInflater;
202import android.view.View;
203import android.view.WindowManager;
204
205import dalvik.system.VMRuntime;
206
207import java.io.BufferedInputStream;
208import java.io.BufferedOutputStream;
209import java.io.DataInputStream;
210import java.io.DataOutputStream;
211import java.io.File;
212import java.io.FileDescriptor;
213import java.io.FileInputStream;
214import java.io.FileNotFoundException;
215import java.io.FileOutputStream;
216import java.io.IOException;
217import java.io.InputStreamReader;
218import java.io.PrintWriter;
219import java.io.StringWriter;
220import java.lang.ref.WeakReference;
221import java.util.ArrayList;
222import java.util.Arrays;
223import java.util.Collections;
224import java.util.Comparator;
225import java.util.HashMap;
226import java.util.HashSet;
227import java.util.Iterator;
228import java.util.List;
229import java.util.Locale;
230import java.util.Map;
231import java.util.Set;
232import java.util.concurrent.atomic.AtomicBoolean;
233import java.util.concurrent.atomic.AtomicLong;
234
235public final class ActivityManagerService extends ActivityManagerNative
236        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
237
238    private static final String USER_DATA_DIR = "/data/user/";
239    // File that stores last updated system version and called preboot receivers
240    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
241
242    static final String TAG = "ActivityManager";
243    static final String TAG_MU = "ActivityManagerServiceMU";
244    static final boolean DEBUG = false;
245    static final boolean localLOGV = DEBUG;
246    static final boolean DEBUG_BACKUP = localLOGV || false;
247    static final boolean DEBUG_BROADCAST = localLOGV || false;
248    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
249    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
250    static final boolean DEBUG_CLEANUP = localLOGV || false;
251    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
252    static final boolean DEBUG_FOCUS = false;
253    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
254    static final boolean DEBUG_MU = localLOGV || false;
255    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
256    static final boolean DEBUG_LRU = localLOGV || false;
257    static final boolean DEBUG_PAUSE = localLOGV || false;
258    static final boolean DEBUG_POWER = localLOGV || false;
259    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
260    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
261    static final boolean DEBUG_PROCESSES = localLOGV || false;
262    static final boolean DEBUG_PROVIDER = localLOGV || false;
263    static final boolean DEBUG_RESULTS = localLOGV || false;
264    static final boolean DEBUG_SERVICE = localLOGV || false;
265    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
266    static final boolean DEBUG_STACK = localLOGV || false;
267    static final boolean DEBUG_SWITCH = localLOGV || false;
268    static final boolean DEBUG_TASKS = localLOGV || false;
269    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
270    static final boolean DEBUG_TRANSITION = localLOGV || false;
271    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
272    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
273    static final boolean DEBUG_VISBILITY = localLOGV || false;
274    static final boolean DEBUG_PSS = localLOGV || false;
275    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
276    static final boolean DEBUG_RECENTS = localLOGV || false;
277    static final boolean VALIDATE_TOKENS = false;
278    static final boolean SHOW_ACTIVITY_START_TIME = true;
279
280    // Control over CPU and battery monitoring.
281    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
282    static final boolean MONITOR_CPU_USAGE = true;
283    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
284    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
285    static final boolean MONITOR_THREAD_CPU_USAGE = false;
286
287    // The flags that are set for all calls we make to the package manager.
288    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
289
290    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
291
292    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
293
294    // Maximum number recent bitmaps to keep in memory.
295    static final int MAX_RECENT_BITMAPS = 5;
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    /** All system services */
374    SystemServiceManager mSystemServiceManager;
375
376    private Installer mInstaller;
377
378    /** Run all ActivityStacks through this */
379    ActivityStackSupervisor mStackSupervisor;
380
381    public IntentFirewall mIntentFirewall;
382
383    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
384    // default actuion automatically.  Important for devices without direct input
385    // devices.
386    private boolean mShowDialogs = true;
387
388    BroadcastQueue mFgBroadcastQueue;
389    BroadcastQueue mBgBroadcastQueue;
390    // Convenient for easy iteration over the queues. Foreground is first
391    // so that dispatch of foreground broadcasts gets precedence.
392    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
393
394    BroadcastQueue broadcastQueueForIntent(Intent intent) {
395        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
396        if (DEBUG_BACKGROUND_BROADCAST) {
397            Slog.i(TAG, "Broadcast intent " + intent + " on "
398                    + (isFg ? "foreground" : "background")
399                    + " queue");
400        }
401        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
402    }
403
404    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
405        for (BroadcastQueue queue : mBroadcastQueues) {
406            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
407            if (r != null) {
408                return r;
409            }
410        }
411        return null;
412    }
413
414    /**
415     * Activity we have told the window manager to have key focus.
416     */
417    ActivityRecord mFocusedActivity = null;
418
419    /**
420     * List of intents that were used to start the most recent tasks.
421     */
422    ArrayList<TaskRecord> mRecentTasks;
423    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
424
425    /**
426     * For addAppTask: cached of the last activity component that was added.
427     */
428    ComponentName mLastAddedTaskComponent;
429
430    /**
431     * For addAppTask: cached of the last activity uid that was added.
432     */
433    int mLastAddedTaskUid;
434
435    /**
436     * For addAppTask: cached of the last ActivityInfo that was added.
437     */
438    ActivityInfo mLastAddedTaskActivity;
439
440    public class PendingAssistExtras extends Binder implements Runnable {
441        public final ActivityRecord activity;
442        public final Bundle extras;
443        public final Intent intent;
444        public final String hint;
445        public final int userHandle;
446        public boolean haveResult = false;
447        public Bundle result = null;
448        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
449                String _hint, int _userHandle) {
450            activity = _activity;
451            extras = _extras;
452            intent = _intent;
453            hint = _hint;
454            userHandle = _userHandle;
455        }
456        @Override
457        public void run() {
458            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
459            synchronized (this) {
460                haveResult = true;
461                notifyAll();
462            }
463        }
464    }
465
466    final ArrayList<PendingAssistExtras> mPendingAssistExtras
467            = new ArrayList<PendingAssistExtras>();
468
469    /**
470     * Process management.
471     */
472    final ProcessList mProcessList = new ProcessList();
473
474    /**
475     * All of the applications we currently have running organized by name.
476     * The keys are strings of the application package name (as
477     * returned by the package manager), and the keys are ApplicationRecord
478     * objects.
479     */
480    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
481
482    /**
483     * Tracking long-term execution of processes to look for abuse and other
484     * bad app behavior.
485     */
486    final ProcessStatsService mProcessStats;
487
488    /**
489     * The currently running isolated processes.
490     */
491    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
492
493    /**
494     * Counter for assigning isolated process uids, to avoid frequently reusing the
495     * same ones.
496     */
497    int mNextIsolatedProcessUid = 0;
498
499    /**
500     * The currently running heavy-weight process, if any.
501     */
502    ProcessRecord mHeavyWeightProcess = null;
503
504    /**
505     * The last time that various processes have crashed.
506     */
507    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
508
509    /**
510     * Information about a process that is currently marked as bad.
511     */
512    static final class BadProcessInfo {
513        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
514            this.time = time;
515            this.shortMsg = shortMsg;
516            this.longMsg = longMsg;
517            this.stack = stack;
518        }
519
520        final long time;
521        final String shortMsg;
522        final String longMsg;
523        final String stack;
524    }
525
526    /**
527     * Set of applications that we consider to be bad, and will reject
528     * incoming broadcasts from (which the user has no control over).
529     * Processes are added to this set when they have crashed twice within
530     * a minimum amount of time; they are removed from it when they are
531     * later restarted (hopefully due to some user action).  The value is the
532     * time it was added to the list.
533     */
534    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
535
536    /**
537     * All of the processes we currently have running organized by pid.
538     * The keys are the pid running the application.
539     *
540     * <p>NOTE: This object is protected by its own lock, NOT the global
541     * activity manager lock!
542     */
543    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
544
545    /**
546     * All of the processes that have been forced to be foreground.  The key
547     * is the pid of the caller who requested it (we hold a death
548     * link on it).
549     */
550    abstract class ForegroundToken implements IBinder.DeathRecipient {
551        int pid;
552        IBinder token;
553    }
554    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
555
556    /**
557     * List of records for processes that someone had tried to start before the
558     * system was ready.  We don't start them at that point, but ensure they
559     * are started by the time booting is complete.
560     */
561    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
562
563    /**
564     * List of persistent applications that are in the process
565     * of being started.
566     */
567    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
568
569    /**
570     * Processes that are being forcibly torn down.
571     */
572    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
573
574    /**
575     * List of running applications, sorted by recent usage.
576     * The first entry in the list is the least recently used.
577     */
578    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
579
580    /**
581     * Where in mLruProcesses that the processes hosting activities start.
582     */
583    int mLruProcessActivityStart = 0;
584
585    /**
586     * Where in mLruProcesses that the processes hosting services start.
587     * This is after (lower index) than mLruProcessesActivityStart.
588     */
589    int mLruProcessServiceStart = 0;
590
591    /**
592     * List of processes that should gc as soon as things are idle.
593     */
594    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
595
596    /**
597     * Processes we want to collect PSS data from.
598     */
599    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
600
601    /**
602     * Last time we requested PSS data of all processes.
603     */
604    long mLastFullPssTime = SystemClock.uptimeMillis();
605
606    /**
607     * If set, the next time we collect PSS data we should do a full collection
608     * with data from native processes and the kernel.
609     */
610    boolean mFullPssPending = false;
611
612    /**
613     * This is the process holding what we currently consider to be
614     * the "home" activity.
615     */
616    ProcessRecord mHomeProcess;
617
618    /**
619     * This is the process holding the activity the user last visited that
620     * is in a different process from the one they are currently in.
621     */
622    ProcessRecord mPreviousProcess;
623
624    /**
625     * The time at which the previous process was last visible.
626     */
627    long mPreviousProcessVisibleTime;
628
629    /**
630     * Which uses have been started, so are allowed to run code.
631     */
632    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
633
634    /**
635     * LRU list of history of current users.  Most recently current is at the end.
636     */
637    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
638
639    /**
640     * Constant array of the users that are currently started.
641     */
642    int[] mStartedUserArray = new int[] { 0 };
643
644    /**
645     * Registered observers of the user switching mechanics.
646     */
647    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
648            = new RemoteCallbackList<IUserSwitchObserver>();
649
650    /**
651     * Currently active user switch.
652     */
653    Object mCurUserSwitchCallback;
654
655    /**
656     * Packages that the user has asked to have run in screen size
657     * compatibility mode instead of filling the screen.
658     */
659    final CompatModePackages mCompatModePackages;
660
661    /**
662     * Set of IntentSenderRecord objects that are currently active.
663     */
664    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
665            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
666
667    /**
668     * Fingerprints (hashCode()) of stack traces that we've
669     * already logged DropBox entries for.  Guarded by itself.  If
670     * something (rogue user app) forces this over
671     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
672     */
673    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
674    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
675
676    /**
677     * Strict Mode background batched logging state.
678     *
679     * The string buffer is guarded by itself, and its lock is also
680     * used to determine if another batched write is already
681     * in-flight.
682     */
683    private final StringBuilder mStrictModeBuffer = new StringBuilder();
684
685    /**
686     * Keeps track of all IIntentReceivers that have been registered for
687     * broadcasts.  Hash keys are the receiver IBinder, hash value is
688     * a ReceiverList.
689     */
690    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
691            new HashMap<IBinder, ReceiverList>();
692
693    /**
694     * Resolver for broadcast intents to registered receivers.
695     * Holds BroadcastFilter (subclass of IntentFilter).
696     */
697    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
698            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
699        @Override
700        protected boolean allowFilterResult(
701                BroadcastFilter filter, List<BroadcastFilter> dest) {
702            IBinder target = filter.receiverList.receiver.asBinder();
703            for (int i=dest.size()-1; i>=0; i--) {
704                if (dest.get(i).receiverList.receiver.asBinder() == target) {
705                    return false;
706                }
707            }
708            return true;
709        }
710
711        @Override
712        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
713            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
714                    || userId == filter.owningUserId) {
715                return super.newResult(filter, match, userId);
716            }
717            return null;
718        }
719
720        @Override
721        protected BroadcastFilter[] newArray(int size) {
722            return new BroadcastFilter[size];
723        }
724
725        @Override
726        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
727            return packageName.equals(filter.packageName);
728        }
729    };
730
731    /**
732     * State of all active sticky broadcasts per user.  Keys are the action of the
733     * sticky Intent, values are an ArrayList of all broadcasted intents with
734     * that action (which should usually be one).  The SparseArray is keyed
735     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
736     * for stickies that are sent to all users.
737     */
738    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
739            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
740
741    final ActiveServices mServices;
742
743    /**
744     * Backup/restore process management
745     */
746    String mBackupAppName = null;
747    BackupRecord mBackupTarget = null;
748
749    final ProviderMap mProviderMap;
750
751    /**
752     * List of content providers who have clients waiting for them.  The
753     * application is currently being launched and the provider will be
754     * removed from this list once it is published.
755     */
756    final ArrayList<ContentProviderRecord> mLaunchingProviders
757            = new ArrayList<ContentProviderRecord>();
758
759    /**
760     * File storing persisted {@link #mGrantedUriPermissions}.
761     */
762    private final AtomicFile mGrantFile;
763
764    /** XML constants used in {@link #mGrantFile} */
765    private static final String TAG_URI_GRANTS = "uri-grants";
766    private static final String TAG_URI_GRANT = "uri-grant";
767    private static final String ATTR_USER_HANDLE = "userHandle";
768    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
769    private static final String ATTR_TARGET_USER_ID = "targetUserId";
770    private static final String ATTR_SOURCE_PKG = "sourcePkg";
771    private static final String ATTR_TARGET_PKG = "targetPkg";
772    private static final String ATTR_URI = "uri";
773    private static final String ATTR_MODE_FLAGS = "modeFlags";
774    private static final String ATTR_CREATED_TIME = "createdTime";
775    private static final String ATTR_PREFIX = "prefix";
776
777    /**
778     * Global set of specific {@link Uri} permissions that have been granted.
779     * This optimized lookup structure maps from {@link UriPermission#targetUid}
780     * to {@link UriPermission#uri} to {@link UriPermission}.
781     */
782    @GuardedBy("this")
783    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
784            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
785
786    public static class GrantUri {
787        public final int sourceUserId;
788        public final Uri uri;
789        public boolean prefix;
790
791        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
792            this.sourceUserId = sourceUserId;
793            this.uri = uri;
794            this.prefix = prefix;
795        }
796
797        @Override
798        public int hashCode() {
799            return toString().hashCode();
800        }
801
802        @Override
803        public boolean equals(Object o) {
804            if (o instanceof GrantUri) {
805                GrantUri other = (GrantUri) o;
806                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
807                        && prefix == other.prefix;
808            }
809            return false;
810        }
811
812        @Override
813        public String toString() {
814            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
815            if (prefix) result += " [prefix]";
816            return result;
817        }
818
819        public String toSafeString() {
820            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
821            if (prefix) result += " [prefix]";
822            return result;
823        }
824
825        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
826            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
827                    ContentProvider.getUriWithoutUserId(uri), false);
828        }
829    }
830
831    CoreSettingsObserver mCoreSettingsObserver;
832
833    /**
834     * Thread-local storage used to carry caller permissions over through
835     * indirect content-provider access.
836     */
837    private class Identity {
838        public int pid;
839        public int uid;
840
841        Identity(int _pid, int _uid) {
842            pid = _pid;
843            uid = _uid;
844        }
845    }
846
847    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
848
849    /**
850     * All information we have collected about the runtime performance of
851     * any user id that can impact battery performance.
852     */
853    final BatteryStatsService mBatteryStatsService;
854
855    /**
856     * Information about component usage
857     */
858    UsageStatsManagerInternal mUsageStatsService;
859
860    /**
861     * Information about and control over application operations
862     */
863    final AppOpsService mAppOpsService;
864
865    /**
866     * Save recent tasks information across reboots.
867     */
868    final TaskPersister mTaskPersister;
869
870    /**
871     * Current configuration information.  HistoryRecord objects are given
872     * a reference to this object to indicate which configuration they are
873     * currently running in, so this object must be kept immutable.
874     */
875    Configuration mConfiguration = new Configuration();
876
877    /**
878     * Current sequencing integer of the configuration, for skipping old
879     * configurations.
880     */
881    int mConfigurationSeq = 0;
882
883    /**
884     * Hardware-reported OpenGLES version.
885     */
886    final int GL_ES_VERSION;
887
888    /**
889     * List of initialization arguments to pass to all processes when binding applications to them.
890     * For example, references to the commonly used services.
891     */
892    HashMap<String, IBinder> mAppBindArgs;
893
894    /**
895     * Temporary to avoid allocations.  Protected by main lock.
896     */
897    final StringBuilder mStringBuilder = new StringBuilder(256);
898
899    /**
900     * Used to control how we initialize the service.
901     */
902    ComponentName mTopComponent;
903    String mTopAction = Intent.ACTION_MAIN;
904    String mTopData;
905    boolean mProcessesReady = false;
906    boolean mSystemReady = false;
907    boolean mBooting = false;
908    boolean mCallFinishBooting = false;
909    boolean mBootAnimationComplete = false;
910    boolean mWaitingUpdate = false;
911    boolean mDidUpdate = false;
912    boolean mOnBattery = false;
913    boolean mLaunchWarningShown = false;
914
915    Context mContext;
916
917    int mFactoryTest;
918
919    boolean mCheckedForSetup;
920
921    /**
922     * The time at which we will allow normal application switches again,
923     * after a call to {@link #stopAppSwitches()}.
924     */
925    long mAppSwitchesAllowedTime;
926
927    /**
928     * This is set to true after the first switch after mAppSwitchesAllowedTime
929     * is set; any switches after that will clear the time.
930     */
931    boolean mDidAppSwitch;
932
933    /**
934     * Last time (in realtime) at which we checked for power usage.
935     */
936    long mLastPowerCheckRealtime;
937
938    /**
939     * Last time (in uptime) at which we checked for power usage.
940     */
941    long mLastPowerCheckUptime;
942
943    /**
944     * Set while we are wanting to sleep, to prevent any
945     * activities from being started/resumed.
946     */
947    private boolean mSleeping = false;
948
949    /**
950     * Set while we are running a voice interaction.  This overrides
951     * sleeping while it is active.
952     */
953    private boolean mRunningVoice = false;
954
955    /**
956     * State of external calls telling us if the device is asleep.
957     */
958    private boolean mWentToSleep = false;
959
960    static final int LOCK_SCREEN_HIDDEN = 0;
961    static final int LOCK_SCREEN_LEAVING = 1;
962    static final int LOCK_SCREEN_SHOWN = 2;
963    /**
964     * State of external call telling us if the lock screen is shown.
965     */
966    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
967
968    /**
969     * Set if we are shutting down the system, similar to sleeping.
970     */
971    boolean mShuttingDown = false;
972
973    /**
974     * Current sequence id for oom_adj computation traversal.
975     */
976    int mAdjSeq = 0;
977
978    /**
979     * Current sequence id for process LRU updating.
980     */
981    int mLruSeq = 0;
982
983    /**
984     * Keep track of the non-cached/empty process we last found, to help
985     * determine how to distribute cached/empty processes next time.
986     */
987    int mNumNonCachedProcs = 0;
988
989    /**
990     * Keep track of the number of cached hidden procs, to balance oom adj
991     * distribution between those and empty procs.
992     */
993    int mNumCachedHiddenProcs = 0;
994
995    /**
996     * Keep track of the number of service processes we last found, to
997     * determine on the next iteration which should be B services.
998     */
999    int mNumServiceProcs = 0;
1000    int mNewNumAServiceProcs = 0;
1001    int mNewNumServiceProcs = 0;
1002
1003    /**
1004     * Allow the current computed overall memory level of the system to go down?
1005     * This is set to false when we are killing processes for reasons other than
1006     * memory management, so that the now smaller process list will not be taken as
1007     * an indication that memory is tighter.
1008     */
1009    boolean mAllowLowerMemLevel = false;
1010
1011    /**
1012     * The last computed memory level, for holding when we are in a state that
1013     * processes are going away for other reasons.
1014     */
1015    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1016
1017    /**
1018     * The last total number of process we have, to determine if changes actually look
1019     * like a shrinking number of process due to lower RAM.
1020     */
1021    int mLastNumProcesses;
1022
1023    /**
1024     * The uptime of the last time we performed idle maintenance.
1025     */
1026    long mLastIdleTime = SystemClock.uptimeMillis();
1027
1028    /**
1029     * Total time spent with RAM that has been added in the past since the last idle time.
1030     */
1031    long mLowRamTimeSinceLastIdle = 0;
1032
1033    /**
1034     * If RAM is currently low, when that horrible situation started.
1035     */
1036    long mLowRamStartTime = 0;
1037
1038    /**
1039     * For reporting to battery stats the current top application.
1040     */
1041    private String mCurResumedPackage = null;
1042    private int mCurResumedUid = -1;
1043
1044    /**
1045     * For reporting to battery stats the apps currently running foreground
1046     * service.  The ProcessMap is package/uid tuples; each of these contain
1047     * an array of the currently foreground processes.
1048     */
1049    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1050            = new ProcessMap<ArrayList<ProcessRecord>>();
1051
1052    /**
1053     * This is set if we had to do a delayed dexopt of an app before launching
1054     * it, to increase the ANR timeouts in that case.
1055     */
1056    boolean mDidDexOpt;
1057
1058    /**
1059     * Set if the systemServer made a call to enterSafeMode.
1060     */
1061    boolean mSafeMode;
1062
1063    String mDebugApp = null;
1064    boolean mWaitForDebugger = false;
1065    boolean mDebugTransient = false;
1066    String mOrigDebugApp = null;
1067    boolean mOrigWaitForDebugger = false;
1068    boolean mAlwaysFinishActivities = false;
1069    IActivityController mController = null;
1070    String mProfileApp = null;
1071    ProcessRecord mProfileProc = null;
1072    String mProfileFile;
1073    ParcelFileDescriptor mProfileFd;
1074    int mSamplingInterval = 0;
1075    boolean mAutoStopProfiler = false;
1076    int mProfileType = 0;
1077    String mOpenGlTraceApp = null;
1078
1079    static class ProcessChangeItem {
1080        static final int CHANGE_ACTIVITIES = 1<<0;
1081        static final int CHANGE_PROCESS_STATE = 1<<1;
1082        int changes;
1083        int uid;
1084        int pid;
1085        int processState;
1086        boolean foregroundActivities;
1087    }
1088
1089    final RemoteCallbackList<IProcessObserver> mProcessObservers
1090            = new RemoteCallbackList<IProcessObserver>();
1091    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1092
1093    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1094            = new ArrayList<ProcessChangeItem>();
1095    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1096            = new ArrayList<ProcessChangeItem>();
1097
1098    /**
1099     * Runtime CPU use collection thread.  This object's lock is used to
1100     * perform synchronization with the thread (notifying it to run).
1101     */
1102    final Thread mProcessCpuThread;
1103
1104    /**
1105     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1106     * Must acquire this object's lock when accessing it.
1107     * NOTE: this lock will be held while doing long operations (trawling
1108     * through all processes in /proc), so it should never be acquired by
1109     * any critical paths such as when holding the main activity manager lock.
1110     */
1111    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1112            MONITOR_THREAD_CPU_USAGE);
1113    final AtomicLong mLastCpuTime = new AtomicLong(0);
1114    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1115
1116    long mLastWriteTime = 0;
1117
1118    /**
1119     * Used to retain an update lock when the foreground activity is in
1120     * immersive mode.
1121     */
1122    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1123
1124    /**
1125     * Set to true after the system has finished booting.
1126     */
1127    boolean mBooted = false;
1128
1129    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1130    int mProcessLimitOverride = -1;
1131
1132    WindowManagerService mWindowManager;
1133
1134    final ActivityThread mSystemThread;
1135
1136    // Holds the current foreground user's id
1137    int mCurrentUserId = 0;
1138    // Holds the target user's id during a user switch
1139    int mTargetUserId = UserHandle.USER_NULL;
1140    // If there are multiple profiles for the current user, their ids are here
1141    // Currently only the primary user can have managed profiles
1142    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1143
1144    /**
1145     * Mapping from each known user ID to the profile group ID it is associated with.
1146     */
1147    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1148
1149    private UserManagerService mUserManager;
1150
1151    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1152        final ProcessRecord mApp;
1153        final int mPid;
1154        final IApplicationThread mAppThread;
1155
1156        AppDeathRecipient(ProcessRecord app, int pid,
1157                IApplicationThread thread) {
1158            if (localLOGV) Slog.v(
1159                TAG, "New death recipient " + this
1160                + " for thread " + thread.asBinder());
1161            mApp = app;
1162            mPid = pid;
1163            mAppThread = thread;
1164        }
1165
1166        @Override
1167        public void binderDied() {
1168            if (localLOGV) Slog.v(
1169                TAG, "Death received in " + this
1170                + " for thread " + mAppThread.asBinder());
1171            synchronized(ActivityManagerService.this) {
1172                appDiedLocked(mApp, mPid, mAppThread);
1173            }
1174        }
1175    }
1176
1177    static final int SHOW_ERROR_MSG = 1;
1178    static final int SHOW_NOT_RESPONDING_MSG = 2;
1179    static final int SHOW_FACTORY_ERROR_MSG = 3;
1180    static final int UPDATE_CONFIGURATION_MSG = 4;
1181    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1182    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1183    static final int SERVICE_TIMEOUT_MSG = 12;
1184    static final int UPDATE_TIME_ZONE = 13;
1185    static final int SHOW_UID_ERROR_MSG = 14;
1186    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1187    static final int PROC_START_TIMEOUT_MSG = 20;
1188    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1189    static final int KILL_APPLICATION_MSG = 22;
1190    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1191    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1192    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1193    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1194    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1195    static final int CLEAR_DNS_CACHE_MSG = 28;
1196    static final int UPDATE_HTTP_PROXY_MSG = 29;
1197    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1198    static final int DISPATCH_PROCESSES_CHANGED = 31;
1199    static final int DISPATCH_PROCESS_DIED = 32;
1200    static final int REPORT_MEM_USAGE_MSG = 33;
1201    static final int REPORT_USER_SWITCH_MSG = 34;
1202    static final int CONTINUE_USER_SWITCH_MSG = 35;
1203    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1204    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1205    static final int PERSIST_URI_GRANTS_MSG = 38;
1206    static final int REQUEST_ALL_PSS_MSG = 39;
1207    static final int START_PROFILES_MSG = 40;
1208    static final int UPDATE_TIME = 41;
1209    static final int SYSTEM_USER_START_MSG = 42;
1210    static final int SYSTEM_USER_CURRENT_MSG = 43;
1211    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1212    static final int FINISH_BOOTING_MSG = 45;
1213    static final int START_USER_SWITCH_MSG = 46;
1214    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1215    static final int DISMISS_DIALOG_MSG = 48;
1216
1217    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1218    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1219    static final int FIRST_COMPAT_MODE_MSG = 300;
1220    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1221
1222    CompatModeDialog mCompatModeDialog;
1223    long mLastMemUsageReportTime = 0;
1224
1225    /**
1226     * Flag whether the current user is a "monkey", i.e. whether
1227     * the UI is driven by a UI automation tool.
1228     */
1229    private boolean mUserIsMonkey;
1230
1231    /** Flag whether the device has a Recents UI */
1232    boolean mHasRecents;
1233
1234    /** The dimensions of the thumbnails in the Recents UI. */
1235    int mThumbnailWidth;
1236    int mThumbnailHeight;
1237
1238    final ServiceThread mHandlerThread;
1239    final MainHandler mHandler;
1240
1241    final class MainHandler extends Handler {
1242        public MainHandler(Looper looper) {
1243            super(looper, null, true);
1244        }
1245
1246        @Override
1247        public void handleMessage(Message msg) {
1248            switch (msg.what) {
1249            case SHOW_ERROR_MSG: {
1250                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1251                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1252                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1253                synchronized (ActivityManagerService.this) {
1254                    ProcessRecord proc = (ProcessRecord)data.get("app");
1255                    AppErrorResult res = (AppErrorResult) data.get("result");
1256                    if (proc != null && proc.crashDialog != null) {
1257                        Slog.e(TAG, "App already has crash dialog: " + proc);
1258                        if (res != null) {
1259                            res.set(0);
1260                        }
1261                        return;
1262                    }
1263                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1264                            >= Process.FIRST_APPLICATION_UID
1265                            && proc.pid != MY_PID);
1266                    for (int userId : mCurrentProfileIds) {
1267                        isBackground &= (proc.userId != userId);
1268                    }
1269                    if (isBackground && !showBackground) {
1270                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1271                        if (res != null) {
1272                            res.set(0);
1273                        }
1274                        return;
1275                    }
1276                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1277                        Dialog d = new AppErrorDialog(mContext,
1278                                ActivityManagerService.this, res, proc);
1279                        d.show();
1280                        proc.crashDialog = d;
1281                    } else {
1282                        // The device is asleep, so just pretend that the user
1283                        // saw a crash dialog and hit "force quit".
1284                        if (res != null) {
1285                            res.set(0);
1286                        }
1287                    }
1288                }
1289
1290                ensureBootCompleted();
1291            } break;
1292            case SHOW_NOT_RESPONDING_MSG: {
1293                synchronized (ActivityManagerService.this) {
1294                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1295                    ProcessRecord proc = (ProcessRecord)data.get("app");
1296                    if (proc != null && proc.anrDialog != null) {
1297                        Slog.e(TAG, "App already has anr dialog: " + proc);
1298                        return;
1299                    }
1300
1301                    Intent intent = new Intent("android.intent.action.ANR");
1302                    if (!mProcessesReady) {
1303                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1304                                | Intent.FLAG_RECEIVER_FOREGROUND);
1305                    }
1306                    broadcastIntentLocked(null, null, intent,
1307                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1308                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1309
1310                    if (mShowDialogs) {
1311                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1312                                mContext, proc, (ActivityRecord)data.get("activity"),
1313                                msg.arg1 != 0);
1314                        d.show();
1315                        proc.anrDialog = d;
1316                    } else {
1317                        // Just kill the app if there is no dialog to be shown.
1318                        killAppAtUsersRequest(proc, null);
1319                    }
1320                }
1321
1322                ensureBootCompleted();
1323            } break;
1324            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1325                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1326                synchronized (ActivityManagerService.this) {
1327                    ProcessRecord proc = (ProcessRecord) data.get("app");
1328                    if (proc == null) {
1329                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1330                        break;
1331                    }
1332                    if (proc.crashDialog != null) {
1333                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1334                        return;
1335                    }
1336                    AppErrorResult res = (AppErrorResult) data.get("result");
1337                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1338                        Dialog d = new StrictModeViolationDialog(mContext,
1339                                ActivityManagerService.this, res, proc);
1340                        d.show();
1341                        proc.crashDialog = d;
1342                    } else {
1343                        // The device is asleep, so just pretend that the user
1344                        // saw a crash dialog and hit "force quit".
1345                        res.set(0);
1346                    }
1347                }
1348                ensureBootCompleted();
1349            } break;
1350            case SHOW_FACTORY_ERROR_MSG: {
1351                Dialog d = new FactoryErrorDialog(
1352                    mContext, msg.getData().getCharSequence("msg"));
1353                d.show();
1354                ensureBootCompleted();
1355            } break;
1356            case UPDATE_CONFIGURATION_MSG: {
1357                final ContentResolver resolver = mContext.getContentResolver();
1358                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1359            } break;
1360            case GC_BACKGROUND_PROCESSES_MSG: {
1361                synchronized (ActivityManagerService.this) {
1362                    performAppGcsIfAppropriateLocked();
1363                }
1364            } break;
1365            case WAIT_FOR_DEBUGGER_MSG: {
1366                synchronized (ActivityManagerService.this) {
1367                    ProcessRecord app = (ProcessRecord)msg.obj;
1368                    if (msg.arg1 != 0) {
1369                        if (!app.waitedForDebugger) {
1370                            Dialog d = new AppWaitingForDebuggerDialog(
1371                                    ActivityManagerService.this,
1372                                    mContext, app);
1373                            app.waitDialog = d;
1374                            app.waitedForDebugger = true;
1375                            d.show();
1376                        }
1377                    } else {
1378                        if (app.waitDialog != null) {
1379                            app.waitDialog.dismiss();
1380                            app.waitDialog = null;
1381                        }
1382                    }
1383                }
1384            } break;
1385            case SERVICE_TIMEOUT_MSG: {
1386                if (mDidDexOpt) {
1387                    mDidDexOpt = false;
1388                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1389                    nmsg.obj = msg.obj;
1390                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1391                    return;
1392                }
1393                mServices.serviceTimeout((ProcessRecord)msg.obj);
1394            } break;
1395            case UPDATE_TIME_ZONE: {
1396                synchronized (ActivityManagerService.this) {
1397                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1398                        ProcessRecord r = mLruProcesses.get(i);
1399                        if (r.thread != null) {
1400                            try {
1401                                r.thread.updateTimeZone();
1402                            } catch (RemoteException ex) {
1403                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1404                            }
1405                        }
1406                    }
1407                }
1408            } break;
1409            case CLEAR_DNS_CACHE_MSG: {
1410                synchronized (ActivityManagerService.this) {
1411                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1412                        ProcessRecord r = mLruProcesses.get(i);
1413                        if (r.thread != null) {
1414                            try {
1415                                r.thread.clearDnsCache();
1416                            } catch (RemoteException ex) {
1417                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1418                            }
1419                        }
1420                    }
1421                }
1422            } break;
1423            case UPDATE_HTTP_PROXY_MSG: {
1424                ProxyInfo proxy = (ProxyInfo)msg.obj;
1425                String host = "";
1426                String port = "";
1427                String exclList = "";
1428                Uri pacFileUrl = Uri.EMPTY;
1429                if (proxy != null) {
1430                    host = proxy.getHost();
1431                    port = Integer.toString(proxy.getPort());
1432                    exclList = proxy.getExclusionListAsString();
1433                    pacFileUrl = proxy.getPacFileUrl();
1434                }
1435                synchronized (ActivityManagerService.this) {
1436                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1437                        ProcessRecord r = mLruProcesses.get(i);
1438                        if (r.thread != null) {
1439                            try {
1440                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1441                            } catch (RemoteException ex) {
1442                                Slog.w(TAG, "Failed to update http proxy for: " +
1443                                        r.info.processName);
1444                            }
1445                        }
1446                    }
1447                }
1448            } break;
1449            case SHOW_UID_ERROR_MSG: {
1450                if (mShowDialogs) {
1451                    AlertDialog d = new BaseErrorDialog(mContext);
1452                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1453                    d.setCancelable(false);
1454                    d.setTitle(mContext.getText(R.string.android_system_label));
1455                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1456                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1457                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1458                    d.show();
1459                }
1460            } break;
1461            case SHOW_FINGERPRINT_ERROR_MSG: {
1462                if (mShowDialogs) {
1463                    AlertDialog d = new BaseErrorDialog(mContext);
1464                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1465                    d.setCancelable(false);
1466                    d.setTitle(mContext.getText(R.string.android_system_label));
1467                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1468                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1469                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1470                    d.show();
1471                }
1472            } break;
1473            case PROC_START_TIMEOUT_MSG: {
1474                if (mDidDexOpt) {
1475                    mDidDexOpt = false;
1476                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1477                    nmsg.obj = msg.obj;
1478                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1479                    return;
1480                }
1481                ProcessRecord app = (ProcessRecord)msg.obj;
1482                synchronized (ActivityManagerService.this) {
1483                    processStartTimedOutLocked(app);
1484                }
1485            } break;
1486            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1487                synchronized (ActivityManagerService.this) {
1488                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1489                }
1490            } break;
1491            case KILL_APPLICATION_MSG: {
1492                synchronized (ActivityManagerService.this) {
1493                    int appid = msg.arg1;
1494                    boolean restart = (msg.arg2 == 1);
1495                    Bundle bundle = (Bundle)msg.obj;
1496                    String pkg = bundle.getString("pkg");
1497                    String reason = bundle.getString("reason");
1498                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1499                            false, UserHandle.USER_ALL, reason);
1500                }
1501            } break;
1502            case FINALIZE_PENDING_INTENT_MSG: {
1503                ((PendingIntentRecord)msg.obj).completeFinalize();
1504            } break;
1505            case POST_HEAVY_NOTIFICATION_MSG: {
1506                INotificationManager inm = NotificationManager.getService();
1507                if (inm == null) {
1508                    return;
1509                }
1510
1511                ActivityRecord root = (ActivityRecord)msg.obj;
1512                ProcessRecord process = root.app;
1513                if (process == null) {
1514                    return;
1515                }
1516
1517                try {
1518                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1519                    String text = mContext.getString(R.string.heavy_weight_notification,
1520                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1521                    Notification notification = new Notification();
1522                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1523                    notification.when = 0;
1524                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1525                    notification.tickerText = text;
1526                    notification.defaults = 0; // please be quiet
1527                    notification.sound = null;
1528                    notification.vibrate = null;
1529                    notification.color = mContext.getResources().getColor(
1530                            com.android.internal.R.color.system_notification_accent_color);
1531                    notification.setLatestEventInfo(context, text,
1532                            mContext.getText(R.string.heavy_weight_notification_detail),
1533                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1534                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1535                                    new UserHandle(root.userId)));
1536
1537                    try {
1538                        int[] outId = new int[1];
1539                        inm.enqueueNotificationWithTag("android", "android", null,
1540                                R.string.heavy_weight_notification,
1541                                notification, outId, root.userId);
1542                    } catch (RuntimeException e) {
1543                        Slog.w(ActivityManagerService.TAG,
1544                                "Error showing notification for heavy-weight app", e);
1545                    } catch (RemoteException e) {
1546                    }
1547                } catch (NameNotFoundException e) {
1548                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1549                }
1550            } break;
1551            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1552                INotificationManager inm = NotificationManager.getService();
1553                if (inm == null) {
1554                    return;
1555                }
1556                try {
1557                    inm.cancelNotificationWithTag("android", null,
1558                            R.string.heavy_weight_notification,  msg.arg1);
1559                } catch (RuntimeException e) {
1560                    Slog.w(ActivityManagerService.TAG,
1561                            "Error canceling notification for service", e);
1562                } catch (RemoteException e) {
1563                }
1564            } break;
1565            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1566                synchronized (ActivityManagerService.this) {
1567                    checkExcessivePowerUsageLocked(true);
1568                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1569                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1570                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1571                }
1572            } break;
1573            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1574                synchronized (ActivityManagerService.this) {
1575                    ActivityRecord ar = (ActivityRecord)msg.obj;
1576                    if (mCompatModeDialog != null) {
1577                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1578                                ar.info.applicationInfo.packageName)) {
1579                            return;
1580                        }
1581                        mCompatModeDialog.dismiss();
1582                        mCompatModeDialog = null;
1583                    }
1584                    if (ar != null && false) {
1585                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1586                                ar.packageName)) {
1587                            int mode = mCompatModePackages.computeCompatModeLocked(
1588                                    ar.info.applicationInfo);
1589                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1590                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1591                                mCompatModeDialog = new CompatModeDialog(
1592                                        ActivityManagerService.this, mContext,
1593                                        ar.info.applicationInfo);
1594                                mCompatModeDialog.show();
1595                            }
1596                        }
1597                    }
1598                }
1599                break;
1600            }
1601            case DISPATCH_PROCESSES_CHANGED: {
1602                dispatchProcessesChanged();
1603                break;
1604            }
1605            case DISPATCH_PROCESS_DIED: {
1606                final int pid = msg.arg1;
1607                final int uid = msg.arg2;
1608                dispatchProcessDied(pid, uid);
1609                break;
1610            }
1611            case REPORT_MEM_USAGE_MSG: {
1612                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1613                Thread thread = new Thread() {
1614                    @Override public void run() {
1615                        reportMemUsage(memInfos);
1616                    }
1617                };
1618                thread.start();
1619                break;
1620            }
1621            case START_USER_SWITCH_MSG: {
1622                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1623                break;
1624            }
1625            case REPORT_USER_SWITCH_MSG: {
1626                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1627                break;
1628            }
1629            case CONTINUE_USER_SWITCH_MSG: {
1630                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1631                break;
1632            }
1633            case USER_SWITCH_TIMEOUT_MSG: {
1634                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1635                break;
1636            }
1637            case IMMERSIVE_MODE_LOCK_MSG: {
1638                final boolean nextState = (msg.arg1 != 0);
1639                if (mUpdateLock.isHeld() != nextState) {
1640                    if (DEBUG_IMMERSIVE) {
1641                        final ActivityRecord r = (ActivityRecord) msg.obj;
1642                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1643                    }
1644                    if (nextState) {
1645                        mUpdateLock.acquire();
1646                    } else {
1647                        mUpdateLock.release();
1648                    }
1649                }
1650                break;
1651            }
1652            case PERSIST_URI_GRANTS_MSG: {
1653                writeGrantedUriPermissions();
1654                break;
1655            }
1656            case REQUEST_ALL_PSS_MSG: {
1657                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1658                break;
1659            }
1660            case START_PROFILES_MSG: {
1661                synchronized (ActivityManagerService.this) {
1662                    startProfilesLocked();
1663                }
1664                break;
1665            }
1666            case UPDATE_TIME: {
1667                synchronized (ActivityManagerService.this) {
1668                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1669                        ProcessRecord r = mLruProcesses.get(i);
1670                        if (r.thread != null) {
1671                            try {
1672                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1673                            } catch (RemoteException ex) {
1674                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1675                            }
1676                        }
1677                    }
1678                }
1679                break;
1680            }
1681            case SYSTEM_USER_START_MSG: {
1682                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1683                        Integer.toString(msg.arg1), msg.arg1);
1684                mSystemServiceManager.startUser(msg.arg1);
1685                break;
1686            }
1687            case SYSTEM_USER_CURRENT_MSG: {
1688                mBatteryStatsService.noteEvent(
1689                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1690                        Integer.toString(msg.arg2), msg.arg2);
1691                mBatteryStatsService.noteEvent(
1692                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1693                        Integer.toString(msg.arg1), msg.arg1);
1694                mSystemServiceManager.switchUser(msg.arg1);
1695                break;
1696            }
1697            case ENTER_ANIMATION_COMPLETE_MSG: {
1698                synchronized (ActivityManagerService.this) {
1699                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1700                    if (r != null && r.app != null && r.app.thread != null) {
1701                        try {
1702                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1703                        } catch (RemoteException e) {
1704                        }
1705                    }
1706                }
1707                break;
1708            }
1709            case FINISH_BOOTING_MSG: {
1710                if (msg.arg1 != 0) {
1711                    finishBooting();
1712                }
1713                if (msg.arg2 != 0) {
1714                    enableScreenAfterBoot();
1715                }
1716                break;
1717            }
1718            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1719                try {
1720                    Locale l = (Locale) msg.obj;
1721                    IBinder service = ServiceManager.getService("mount");
1722                    IMountService mountService = IMountService.Stub.asInterface(service);
1723                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1724                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1725                } catch (RemoteException e) {
1726                    Log.e(TAG, "Error storing locale for decryption UI", e);
1727                }
1728                break;
1729            }
1730            case DISMISS_DIALOG_MSG: {
1731                final Dialog d = (Dialog) msg.obj;
1732                d.dismiss();
1733                break;
1734            }
1735            }
1736        }
1737    };
1738
1739    static final int COLLECT_PSS_BG_MSG = 1;
1740
1741    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1742        @Override
1743        public void handleMessage(Message msg) {
1744            switch (msg.what) {
1745            case COLLECT_PSS_BG_MSG: {
1746                long start = SystemClock.uptimeMillis();
1747                MemInfoReader memInfo = null;
1748                synchronized (ActivityManagerService.this) {
1749                    if (mFullPssPending) {
1750                        mFullPssPending = false;
1751                        memInfo = new MemInfoReader();
1752                    }
1753                }
1754                if (memInfo != null) {
1755                    updateCpuStatsNow();
1756                    long nativeTotalPss = 0;
1757                    synchronized (mProcessCpuTracker) {
1758                        final int N = mProcessCpuTracker.countStats();
1759                        for (int j=0; j<N; j++) {
1760                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1761                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1762                                // This is definitely an application process; skip it.
1763                                continue;
1764                            }
1765                            synchronized (mPidsSelfLocked) {
1766                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1767                                    // This is one of our own processes; skip it.
1768                                    continue;
1769                                }
1770                            }
1771                            nativeTotalPss += Debug.getPss(st.pid, null);
1772                        }
1773                    }
1774                    memInfo.readMemInfo();
1775                    synchronized (ActivityManagerService.this) {
1776                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1777                                + (SystemClock.uptimeMillis()-start) + "ms");
1778                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1779                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1780                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1781                    }
1782                }
1783
1784                int i = 0;
1785                int num = 0;
1786                long[] tmp = new long[1];
1787                do {
1788                    ProcessRecord proc;
1789                    int procState;
1790                    int pid;
1791                    synchronized (ActivityManagerService.this) {
1792                        if (i >= mPendingPssProcesses.size()) {
1793                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1794                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1795                            mPendingPssProcesses.clear();
1796                            return;
1797                        }
1798                        proc = mPendingPssProcesses.get(i);
1799                        procState = proc.pssProcState;
1800                        if (proc.thread != null && procState == proc.setProcState) {
1801                            pid = proc.pid;
1802                        } else {
1803                            proc = null;
1804                            pid = 0;
1805                        }
1806                        i++;
1807                    }
1808                    if (proc != null) {
1809                        long pss = Debug.getPss(pid, tmp);
1810                        synchronized (ActivityManagerService.this) {
1811                            if (proc.thread != null && proc.setProcState == procState
1812                                    && proc.pid == pid) {
1813                                num++;
1814                                proc.lastPssTime = SystemClock.uptimeMillis();
1815                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1816                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1817                                        + ": " + pss + " lastPss=" + proc.lastPss
1818                                        + " state=" + ProcessList.makeProcStateString(procState));
1819                                if (proc.initialIdlePss == 0) {
1820                                    proc.initialIdlePss = pss;
1821                                }
1822                                proc.lastPss = pss;
1823                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1824                                    proc.lastCachedPss = pss;
1825                                }
1826                            }
1827                        }
1828                    }
1829                } while (true);
1830            }
1831            }
1832        }
1833    };
1834
1835    /**
1836     * Monitor for package changes and update our internal state.
1837     */
1838    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1839        @Override
1840        public void onPackageRemoved(String packageName, int uid) {
1841            // Remove all tasks with activities in the specified package from the list of recent tasks
1842            final int eventUserId = getChangingUserId();
1843            synchronized (ActivityManagerService.this) {
1844                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1845                    TaskRecord tr = mRecentTasks.get(i);
1846                    if (tr.userId != eventUserId) continue;
1847
1848                    ComponentName cn = tr.intent.getComponent();
1849                    if (cn != null && cn.getPackageName().equals(packageName)) {
1850                        // If the package name matches, remove the task
1851                        removeTaskByIdLocked(tr.taskId, true);
1852                    }
1853                }
1854            }
1855        }
1856
1857        @Override
1858        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1859            onPackageModified(packageName);
1860            return true;
1861        }
1862
1863        @Override
1864        public void onPackageModified(String packageName) {
1865            final int eventUserId = getChangingUserId();
1866            final IPackageManager pm = AppGlobals.getPackageManager();
1867            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1868                    new ArrayList<Pair<Intent, Integer>>();
1869            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
1870            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1871            // Copy the list of recent tasks so that we don't hold onto the lock on
1872            // ActivityManagerService for long periods while checking if components exist.
1873            synchronized (ActivityManagerService.this) {
1874                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1875                    TaskRecord tr = mRecentTasks.get(i);
1876                    if (tr.userId != eventUserId) continue;
1877
1878                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1879                }
1880            }
1881            // Check the recent tasks and filter out all tasks with components that no longer exist.
1882            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1883                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1884                ComponentName cn = p.first.getComponent();
1885                if (cn != null && cn.getPackageName().equals(packageName)) {
1886                    if (componentsKnownToExist.contains(cn)) {
1887                        // If we know that the component still exists in the package, then skip
1888                        continue;
1889                    }
1890                    try {
1891                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
1892                        if (info != null) {
1893                            componentsKnownToExist.add(cn);
1894                        } else {
1895                            tasksToRemove.add(p.second);
1896                        }
1897                    } catch (RemoteException e) {
1898                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
1899                    }
1900                }
1901            }
1902            // Prune all the tasks with removed components from the list of recent tasks
1903            synchronized (ActivityManagerService.this) {
1904                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1905                    removeTaskByIdLocked(tasksToRemove.get(i), false);
1906                }
1907            }
1908        }
1909
1910        @Override
1911        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1912            // Force stop the specified packages
1913            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
1914            if (packages != null) {
1915                for (String pkg : packages) {
1916                    synchronized (ActivityManagerService.this) {
1917                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
1918                                userId, "finished booting")) {
1919                            return true;
1920                        }
1921                    }
1922                }
1923            }
1924            return false;
1925        }
1926    };
1927
1928    public void setSystemProcess() {
1929        try {
1930            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1931            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1932            ServiceManager.addService("meminfo", new MemBinder(this));
1933            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1934            ServiceManager.addService("dbinfo", new DbBinder(this));
1935            if (MONITOR_CPU_USAGE) {
1936                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1937            }
1938            ServiceManager.addService("permission", new PermissionController(this));
1939
1940            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1941                    "android", STOCK_PM_FLAGS);
1942            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1943
1944            synchronized (this) {
1945                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1946                app.persistent = true;
1947                app.pid = MY_PID;
1948                app.maxAdj = ProcessList.SYSTEM_ADJ;
1949                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1950                mProcessNames.put(app.processName, app.uid, app);
1951                synchronized (mPidsSelfLocked) {
1952                    mPidsSelfLocked.put(app.pid, app);
1953                }
1954                updateLruProcessLocked(app, false, null);
1955                updateOomAdjLocked();
1956            }
1957        } catch (PackageManager.NameNotFoundException e) {
1958            throw new RuntimeException(
1959                    "Unable to find android system package", e);
1960        }
1961    }
1962
1963    public void setWindowManager(WindowManagerService wm) {
1964        mWindowManager = wm;
1965        mStackSupervisor.setWindowManager(wm);
1966    }
1967
1968    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1969        mUsageStatsService = usageStatsManager;
1970    }
1971
1972    public void startObservingNativeCrashes() {
1973        final NativeCrashListener ncl = new NativeCrashListener(this);
1974        ncl.start();
1975    }
1976
1977    public IAppOpsService getAppOpsService() {
1978        return mAppOpsService;
1979    }
1980
1981    static class MemBinder extends Binder {
1982        ActivityManagerService mActivityManagerService;
1983        MemBinder(ActivityManagerService activityManagerService) {
1984            mActivityManagerService = activityManagerService;
1985        }
1986
1987        @Override
1988        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1989            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1990                    != PackageManager.PERMISSION_GRANTED) {
1991                pw.println("Permission Denial: can't dump meminfo from from pid="
1992                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1993                        + " without permission " + android.Manifest.permission.DUMP);
1994                return;
1995            }
1996
1997            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1998        }
1999    }
2000
2001    static class GraphicsBinder extends Binder {
2002        ActivityManagerService mActivityManagerService;
2003        GraphicsBinder(ActivityManagerService activityManagerService) {
2004            mActivityManagerService = activityManagerService;
2005        }
2006
2007        @Override
2008        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2009            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2010                    != PackageManager.PERMISSION_GRANTED) {
2011                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2012                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2013                        + " without permission " + android.Manifest.permission.DUMP);
2014                return;
2015            }
2016
2017            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2018        }
2019    }
2020
2021    static class DbBinder extends Binder {
2022        ActivityManagerService mActivityManagerService;
2023        DbBinder(ActivityManagerService activityManagerService) {
2024            mActivityManagerService = activityManagerService;
2025        }
2026
2027        @Override
2028        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2029            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2030                    != PackageManager.PERMISSION_GRANTED) {
2031                pw.println("Permission Denial: can't dump dbinfo from from pid="
2032                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2033                        + " without permission " + android.Manifest.permission.DUMP);
2034                return;
2035            }
2036
2037            mActivityManagerService.dumpDbInfo(fd, pw, args);
2038        }
2039    }
2040
2041    static class CpuBinder extends Binder {
2042        ActivityManagerService mActivityManagerService;
2043        CpuBinder(ActivityManagerService activityManagerService) {
2044            mActivityManagerService = activityManagerService;
2045        }
2046
2047        @Override
2048        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2049            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2050                    != PackageManager.PERMISSION_GRANTED) {
2051                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2052                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2053                        + " without permission " + android.Manifest.permission.DUMP);
2054                return;
2055            }
2056
2057            synchronized (mActivityManagerService.mProcessCpuTracker) {
2058                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2059                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2060                        SystemClock.uptimeMillis()));
2061            }
2062        }
2063    }
2064
2065    public static final class Lifecycle extends SystemService {
2066        private final ActivityManagerService mService;
2067
2068        public Lifecycle(Context context) {
2069            super(context);
2070            mService = new ActivityManagerService(context);
2071        }
2072
2073        @Override
2074        public void onStart() {
2075            mService.start();
2076        }
2077
2078        public ActivityManagerService getService() {
2079            return mService;
2080        }
2081    }
2082
2083    // Note: This method is invoked on the main thread but may need to attach various
2084    // handlers to other threads.  So take care to be explicit about the looper.
2085    public ActivityManagerService(Context systemContext) {
2086        mContext = systemContext;
2087        mFactoryTest = FactoryTest.getMode();
2088        mSystemThread = ActivityThread.currentActivityThread();
2089
2090        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2091
2092        mHandlerThread = new ServiceThread(TAG,
2093                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2094        mHandlerThread.start();
2095        mHandler = new MainHandler(mHandlerThread.getLooper());
2096
2097        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2098                "foreground", BROADCAST_FG_TIMEOUT, false);
2099        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2100                "background", BROADCAST_BG_TIMEOUT, true);
2101        mBroadcastQueues[0] = mFgBroadcastQueue;
2102        mBroadcastQueues[1] = mBgBroadcastQueue;
2103
2104        mServices = new ActiveServices(this);
2105        mProviderMap = new ProviderMap(this);
2106
2107        // TODO: Move creation of battery stats service outside of activity manager service.
2108        File dataDir = Environment.getDataDirectory();
2109        File systemDir = new File(dataDir, "system");
2110        systemDir.mkdirs();
2111        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2112        mBatteryStatsService.getActiveStatistics().readLocked();
2113        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2114        mOnBattery = DEBUG_POWER ? true
2115                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2116        mBatteryStatsService.getActiveStatistics().setCallback(this);
2117
2118        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2119
2120        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2121
2122        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2123
2124        // User 0 is the first and only user that runs at boot.
2125        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2126        mUserLru.add(Integer.valueOf(0));
2127        updateStartedUserArrayLocked();
2128
2129        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2130            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2131
2132        mConfiguration.setToDefaults();
2133        mConfiguration.setLocale(Locale.getDefault());
2134
2135        mConfigurationSeq = mConfiguration.seq = 1;
2136        mProcessCpuTracker.init();
2137
2138        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2139        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2140        mStackSupervisor = new ActivityStackSupervisor(this);
2141        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2142
2143        mProcessCpuThread = new Thread("CpuTracker") {
2144            @Override
2145            public void run() {
2146                while (true) {
2147                    try {
2148                        try {
2149                            synchronized(this) {
2150                                final long now = SystemClock.uptimeMillis();
2151                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2152                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2153                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2154                                //        + ", write delay=" + nextWriteDelay);
2155                                if (nextWriteDelay < nextCpuDelay) {
2156                                    nextCpuDelay = nextWriteDelay;
2157                                }
2158                                if (nextCpuDelay > 0) {
2159                                    mProcessCpuMutexFree.set(true);
2160                                    this.wait(nextCpuDelay);
2161                                }
2162                            }
2163                        } catch (InterruptedException e) {
2164                        }
2165                        updateCpuStatsNow();
2166                    } catch (Exception e) {
2167                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2168                    }
2169                }
2170            }
2171        };
2172
2173        Watchdog.getInstance().addMonitor(this);
2174        Watchdog.getInstance().addThread(mHandler);
2175    }
2176
2177    public void setSystemServiceManager(SystemServiceManager mgr) {
2178        mSystemServiceManager = mgr;
2179    }
2180
2181    public void setInstaller(Installer installer) {
2182        mInstaller = installer;
2183    }
2184
2185    private void start() {
2186        Process.removeAllProcessGroups();
2187        mProcessCpuThread.start();
2188
2189        mBatteryStatsService.publish(mContext);
2190        mAppOpsService.publish(mContext);
2191        Slog.d("AppOps", "AppOpsService published");
2192        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2193    }
2194
2195    public void initPowerManagement() {
2196        mStackSupervisor.initPowerManagement();
2197        mBatteryStatsService.initPowerManagement();
2198    }
2199
2200    @Override
2201    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2202            throws RemoteException {
2203        if (code == SYSPROPS_TRANSACTION) {
2204            // We need to tell all apps about the system property change.
2205            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2206            synchronized(this) {
2207                final int NP = mProcessNames.getMap().size();
2208                for (int ip=0; ip<NP; ip++) {
2209                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2210                    final int NA = apps.size();
2211                    for (int ia=0; ia<NA; ia++) {
2212                        ProcessRecord app = apps.valueAt(ia);
2213                        if (app.thread != null) {
2214                            procs.add(app.thread.asBinder());
2215                        }
2216                    }
2217                }
2218            }
2219
2220            int N = procs.size();
2221            for (int i=0; i<N; i++) {
2222                Parcel data2 = Parcel.obtain();
2223                try {
2224                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2225                } catch (RemoteException e) {
2226                }
2227                data2.recycle();
2228            }
2229        }
2230        try {
2231            return super.onTransact(code, data, reply, flags);
2232        } catch (RuntimeException e) {
2233            // The activity manager only throws security exceptions, so let's
2234            // log all others.
2235            if (!(e instanceof SecurityException)) {
2236                Slog.wtf(TAG, "Activity Manager Crash", e);
2237            }
2238            throw e;
2239        }
2240    }
2241
2242    void updateCpuStats() {
2243        final long now = SystemClock.uptimeMillis();
2244        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2245            return;
2246        }
2247        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2248            synchronized (mProcessCpuThread) {
2249                mProcessCpuThread.notify();
2250            }
2251        }
2252    }
2253
2254    void updateCpuStatsNow() {
2255        synchronized (mProcessCpuTracker) {
2256            mProcessCpuMutexFree.set(false);
2257            final long now = SystemClock.uptimeMillis();
2258            boolean haveNewCpuStats = false;
2259
2260            if (MONITOR_CPU_USAGE &&
2261                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2262                mLastCpuTime.set(now);
2263                haveNewCpuStats = true;
2264                mProcessCpuTracker.update();
2265                //Slog.i(TAG, mProcessCpu.printCurrentState());
2266                //Slog.i(TAG, "Total CPU usage: "
2267                //        + mProcessCpu.getTotalCpuPercent() + "%");
2268
2269                // Slog the cpu usage if the property is set.
2270                if ("true".equals(SystemProperties.get("events.cpu"))) {
2271                    int user = mProcessCpuTracker.getLastUserTime();
2272                    int system = mProcessCpuTracker.getLastSystemTime();
2273                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2274                    int irq = mProcessCpuTracker.getLastIrqTime();
2275                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2276                    int idle = mProcessCpuTracker.getLastIdleTime();
2277
2278                    int total = user + system + iowait + irq + softIrq + idle;
2279                    if (total == 0) total = 1;
2280
2281                    EventLog.writeEvent(EventLogTags.CPU,
2282                            ((user+system+iowait+irq+softIrq) * 100) / total,
2283                            (user * 100) / total,
2284                            (system * 100) / total,
2285                            (iowait * 100) / total,
2286                            (irq * 100) / total,
2287                            (softIrq * 100) / total);
2288                }
2289            }
2290
2291            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2292            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2293            synchronized(bstats) {
2294                synchronized(mPidsSelfLocked) {
2295                    if (haveNewCpuStats) {
2296                        if (mOnBattery) {
2297                            int perc = bstats.startAddingCpuLocked();
2298                            int totalUTime = 0;
2299                            int totalSTime = 0;
2300                            final int N = mProcessCpuTracker.countStats();
2301                            for (int i=0; i<N; i++) {
2302                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2303                                if (!st.working) {
2304                                    continue;
2305                                }
2306                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2307                                int otherUTime = (st.rel_utime*perc)/100;
2308                                int otherSTime = (st.rel_stime*perc)/100;
2309                                totalUTime += otherUTime;
2310                                totalSTime += otherSTime;
2311                                if (pr != null) {
2312                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2313                                    if (ps == null || !ps.isActive()) {
2314                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2315                                                pr.info.uid, pr.processName);
2316                                    }
2317                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2318                                            st.rel_stime-otherSTime);
2319                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2320                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2321                                } else {
2322                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2323                                    if (ps == null || !ps.isActive()) {
2324                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2325                                                bstats.mapUid(st.uid), st.name);
2326                                    }
2327                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2328                                            st.rel_stime-otherSTime);
2329                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2330                                }
2331                            }
2332                            bstats.finishAddingCpuLocked(perc, totalUTime,
2333                                    totalSTime, cpuSpeedTimes);
2334                        }
2335                    }
2336                }
2337
2338                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2339                    mLastWriteTime = now;
2340                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2341                }
2342            }
2343        }
2344    }
2345
2346    @Override
2347    public void batteryNeedsCpuUpdate() {
2348        updateCpuStatsNow();
2349    }
2350
2351    @Override
2352    public void batteryPowerChanged(boolean onBattery) {
2353        // When plugging in, update the CPU stats first before changing
2354        // the plug state.
2355        updateCpuStatsNow();
2356        synchronized (this) {
2357            synchronized(mPidsSelfLocked) {
2358                mOnBattery = DEBUG_POWER ? true : onBattery;
2359            }
2360        }
2361    }
2362
2363    /**
2364     * Initialize the application bind args. These are passed to each
2365     * process when the bindApplication() IPC is sent to the process. They're
2366     * lazily setup to make sure the services are running when they're asked for.
2367     */
2368    private HashMap<String, IBinder> getCommonServicesLocked() {
2369        if (mAppBindArgs == null) {
2370            mAppBindArgs = new HashMap<String, IBinder>();
2371
2372            // Setup the application init args
2373            mAppBindArgs.put("package", ServiceManager.getService("package"));
2374            mAppBindArgs.put("window", ServiceManager.getService("window"));
2375            mAppBindArgs.put(Context.ALARM_SERVICE,
2376                    ServiceManager.getService(Context.ALARM_SERVICE));
2377        }
2378        return mAppBindArgs;
2379    }
2380
2381    final void setFocusedActivityLocked(ActivityRecord r) {
2382        if (mFocusedActivity != r) {
2383            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2384            mFocusedActivity = r;
2385            if (r.task != null && r.task.voiceInteractor != null) {
2386                startRunningVoiceLocked();
2387            } else {
2388                finishRunningVoiceLocked();
2389            }
2390            mStackSupervisor.setFocusedStack(r);
2391            if (r != null) {
2392                mWindowManager.setFocusedApp(r.appToken, true);
2393            }
2394            applyUpdateLockStateLocked(r);
2395        }
2396    }
2397
2398    final void clearFocusedActivity(ActivityRecord r) {
2399        if (mFocusedActivity == r) {
2400            mFocusedActivity = null;
2401        }
2402    }
2403
2404    @Override
2405    public void setFocusedStack(int stackId) {
2406        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2407        synchronized (ActivityManagerService.this) {
2408            ActivityStack stack = mStackSupervisor.getStack(stackId);
2409            if (stack != null) {
2410                ActivityRecord r = stack.topRunningActivityLocked(null);
2411                if (r != null) {
2412                    setFocusedActivityLocked(r);
2413                }
2414            }
2415        }
2416    }
2417
2418    @Override
2419    public void notifyActivityDrawn(IBinder token) {
2420        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2421        synchronized (this) {
2422            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2423            if (r != null) {
2424                r.task.stack.notifyActivityDrawnLocked(r);
2425            }
2426        }
2427    }
2428
2429    final void applyUpdateLockStateLocked(ActivityRecord r) {
2430        // Modifications to the UpdateLock state are done on our handler, outside
2431        // the activity manager's locks.  The new state is determined based on the
2432        // state *now* of the relevant activity record.  The object is passed to
2433        // the handler solely for logging detail, not to be consulted/modified.
2434        final boolean nextState = r != null && r.immersive;
2435        mHandler.sendMessage(
2436                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2437    }
2438
2439    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2440        Message msg = Message.obtain();
2441        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2442        msg.obj = r.task.askedCompatMode ? null : r;
2443        mHandler.sendMessage(msg);
2444    }
2445
2446    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2447            String what, Object obj, ProcessRecord srcApp) {
2448        app.lastActivityTime = now;
2449
2450        if (app.activities.size() > 0) {
2451            // Don't want to touch dependent processes that are hosting activities.
2452            return index;
2453        }
2454
2455        int lrui = mLruProcesses.lastIndexOf(app);
2456        if (lrui < 0) {
2457            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2458                    + what + " " + obj + " from " + srcApp);
2459            return index;
2460        }
2461
2462        if (lrui >= index) {
2463            // Don't want to cause this to move dependent processes *back* in the
2464            // list as if they were less frequently used.
2465            return index;
2466        }
2467
2468        if (lrui >= mLruProcessActivityStart) {
2469            // Don't want to touch dependent processes that are hosting activities.
2470            return index;
2471        }
2472
2473        mLruProcesses.remove(lrui);
2474        if (index > 0) {
2475            index--;
2476        }
2477        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2478                + " in LRU list: " + app);
2479        mLruProcesses.add(index, app);
2480        return index;
2481    }
2482
2483    final void removeLruProcessLocked(ProcessRecord app) {
2484        int lrui = mLruProcesses.lastIndexOf(app);
2485        if (lrui >= 0) {
2486            if (!app.killed) {
2487                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2488                Process.killProcessQuiet(app.pid);
2489                Process.killProcessGroup(app.info.uid, app.pid);
2490            }
2491            if (lrui <= mLruProcessActivityStart) {
2492                mLruProcessActivityStart--;
2493            }
2494            if (lrui <= mLruProcessServiceStart) {
2495                mLruProcessServiceStart--;
2496            }
2497            mLruProcesses.remove(lrui);
2498        }
2499    }
2500
2501    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2502            ProcessRecord client) {
2503        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2504                || app.treatLikeActivity;
2505        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2506        if (!activityChange && hasActivity) {
2507            // The process has activities, so we are only allowing activity-based adjustments
2508            // to move it.  It should be kept in the front of the list with other
2509            // processes that have activities, and we don't want those to change their
2510            // order except due to activity operations.
2511            return;
2512        }
2513
2514        mLruSeq++;
2515        final long now = SystemClock.uptimeMillis();
2516        app.lastActivityTime = now;
2517
2518        // First a quick reject: if the app is already at the position we will
2519        // put it, then there is nothing to do.
2520        if (hasActivity) {
2521            final int N = mLruProcesses.size();
2522            if (N > 0 && mLruProcesses.get(N-1) == app) {
2523                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2524                return;
2525            }
2526        } else {
2527            if (mLruProcessServiceStart > 0
2528                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2529                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2530                return;
2531            }
2532        }
2533
2534        int lrui = mLruProcesses.lastIndexOf(app);
2535
2536        if (app.persistent && lrui >= 0) {
2537            // We don't care about the position of persistent processes, as long as
2538            // they are in the list.
2539            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2540            return;
2541        }
2542
2543        /* In progress: compute new position first, so we can avoid doing work
2544           if the process is not actually going to move.  Not yet working.
2545        int addIndex;
2546        int nextIndex;
2547        boolean inActivity = false, inService = false;
2548        if (hasActivity) {
2549            // Process has activities, put it at the very tipsy-top.
2550            addIndex = mLruProcesses.size();
2551            nextIndex = mLruProcessServiceStart;
2552            inActivity = true;
2553        } else if (hasService) {
2554            // Process has services, put it at the top of the service list.
2555            addIndex = mLruProcessActivityStart;
2556            nextIndex = mLruProcessServiceStart;
2557            inActivity = true;
2558            inService = true;
2559        } else  {
2560            // Process not otherwise of interest, it goes to the top of the non-service area.
2561            addIndex = mLruProcessServiceStart;
2562            if (client != null) {
2563                int clientIndex = mLruProcesses.lastIndexOf(client);
2564                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2565                        + app);
2566                if (clientIndex >= 0 && addIndex > clientIndex) {
2567                    addIndex = clientIndex;
2568                }
2569            }
2570            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2571        }
2572
2573        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2574                + mLruProcessActivityStart + "): " + app);
2575        */
2576
2577        if (lrui >= 0) {
2578            if (lrui < mLruProcessActivityStart) {
2579                mLruProcessActivityStart--;
2580            }
2581            if (lrui < mLruProcessServiceStart) {
2582                mLruProcessServiceStart--;
2583            }
2584            /*
2585            if (addIndex > lrui) {
2586                addIndex--;
2587            }
2588            if (nextIndex > lrui) {
2589                nextIndex--;
2590            }
2591            */
2592            mLruProcesses.remove(lrui);
2593        }
2594
2595        /*
2596        mLruProcesses.add(addIndex, app);
2597        if (inActivity) {
2598            mLruProcessActivityStart++;
2599        }
2600        if (inService) {
2601            mLruProcessActivityStart++;
2602        }
2603        */
2604
2605        int nextIndex;
2606        if (hasActivity) {
2607            final int N = mLruProcesses.size();
2608            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2609                // Process doesn't have activities, but has clients with
2610                // activities...  move it up, but one below the top (the top
2611                // should always have a real activity).
2612                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2613                mLruProcesses.add(N-1, app);
2614                // To keep it from spamming the LRU list (by making a bunch of clients),
2615                // we will push down any other entries owned by the app.
2616                final int uid = app.info.uid;
2617                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2618                    ProcessRecord subProc = mLruProcesses.get(i);
2619                    if (subProc.info.uid == uid) {
2620                        // We want to push this one down the list.  If the process after
2621                        // it is for the same uid, however, don't do so, because we don't
2622                        // want them internally to be re-ordered.
2623                        if (mLruProcesses.get(i-1).info.uid != uid) {
2624                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2625                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2626                            ProcessRecord tmp = mLruProcesses.get(i);
2627                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2628                            mLruProcesses.set(i-1, tmp);
2629                            i--;
2630                        }
2631                    } else {
2632                        // A gap, we can stop here.
2633                        break;
2634                    }
2635                }
2636            } else {
2637                // Process has activities, put it at the very tipsy-top.
2638                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2639                mLruProcesses.add(app);
2640            }
2641            nextIndex = mLruProcessServiceStart;
2642        } else if (hasService) {
2643            // Process has services, put it at the top of the service list.
2644            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2645            mLruProcesses.add(mLruProcessActivityStart, app);
2646            nextIndex = mLruProcessServiceStart;
2647            mLruProcessActivityStart++;
2648        } else  {
2649            // Process not otherwise of interest, it goes to the top of the non-service area.
2650            int index = mLruProcessServiceStart;
2651            if (client != null) {
2652                // If there is a client, don't allow the process to be moved up higher
2653                // in the list than that client.
2654                int clientIndex = mLruProcesses.lastIndexOf(client);
2655                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2656                        + " when updating " + app);
2657                if (clientIndex <= lrui) {
2658                    // Don't allow the client index restriction to push it down farther in the
2659                    // list than it already is.
2660                    clientIndex = lrui;
2661                }
2662                if (clientIndex >= 0 && index > clientIndex) {
2663                    index = clientIndex;
2664                }
2665            }
2666            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2667            mLruProcesses.add(index, app);
2668            nextIndex = index-1;
2669            mLruProcessActivityStart++;
2670            mLruProcessServiceStart++;
2671        }
2672
2673        // If the app is currently using a content provider or service,
2674        // bump those processes as well.
2675        for (int j=app.connections.size()-1; j>=0; j--) {
2676            ConnectionRecord cr = app.connections.valueAt(j);
2677            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2678                    && cr.binding.service.app != null
2679                    && cr.binding.service.app.lruSeq != mLruSeq
2680                    && !cr.binding.service.app.persistent) {
2681                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2682                        "service connection", cr, app);
2683            }
2684        }
2685        for (int j=app.conProviders.size()-1; j>=0; j--) {
2686            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2687            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2688                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2689                        "provider reference", cpr, app);
2690            }
2691        }
2692    }
2693
2694    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2695        if (uid == Process.SYSTEM_UID) {
2696            // The system gets to run in any process.  If there are multiple
2697            // processes with the same uid, just pick the first (this
2698            // should never happen).
2699            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2700            if (procs == null) return null;
2701            final int N = procs.size();
2702            for (int i = 0; i < N; i++) {
2703                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2704            }
2705        }
2706        ProcessRecord proc = mProcessNames.get(processName, uid);
2707        if (false && proc != null && !keepIfLarge
2708                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2709                && proc.lastCachedPss >= 4000) {
2710            // Turn this condition on to cause killing to happen regularly, for testing.
2711            if (proc.baseProcessTracker != null) {
2712                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2713            }
2714            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2715        } else if (proc != null && !keepIfLarge
2716                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2717                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2718            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2719            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2720                if (proc.baseProcessTracker != null) {
2721                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2722                }
2723                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2724            }
2725        }
2726        return proc;
2727    }
2728
2729    void ensurePackageDexOpt(String packageName) {
2730        IPackageManager pm = AppGlobals.getPackageManager();
2731        try {
2732            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2733                mDidDexOpt = true;
2734            }
2735        } catch (RemoteException e) {
2736        }
2737    }
2738
2739    boolean isNextTransitionForward() {
2740        int transit = mWindowManager.getPendingAppTransition();
2741        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2742                || transit == AppTransition.TRANSIT_TASK_OPEN
2743                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2744    }
2745
2746    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2747            String processName, String abiOverride, int uid, Runnable crashHandler) {
2748        synchronized(this) {
2749            ApplicationInfo info = new ApplicationInfo();
2750            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2751            // For isolated processes, the former contains the parent's uid and the latter the
2752            // actual uid of the isolated process.
2753            // In the special case introduced by this method (which is, starting an isolated
2754            // process directly from the SystemServer without an actual parent app process) the
2755            // closest thing to a parent's uid is SYSTEM_UID.
2756            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2757            // the |isolated| logic in the ProcessRecord constructor.
2758            info.uid = Process.SYSTEM_UID;
2759            info.processName = processName;
2760            info.className = entryPoint;
2761            info.packageName = "android";
2762            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2763                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2764                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2765                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2766                    crashHandler);
2767            return proc != null ? proc.pid : 0;
2768        }
2769    }
2770
2771    final ProcessRecord startProcessLocked(String processName,
2772            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2773            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2774            boolean isolated, boolean keepIfLarge) {
2775        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2776                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2777                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2778                null /* crashHandler */);
2779    }
2780
2781    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2782            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2783            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2784            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2785        long startTime = SystemClock.elapsedRealtime();
2786        ProcessRecord app;
2787        if (!isolated) {
2788            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2789            checkTime(startTime, "startProcess: after getProcessRecord");
2790        } else {
2791            // If this is an isolated process, it can't re-use an existing process.
2792            app = null;
2793        }
2794        // We don't have to do anything more if:
2795        // (1) There is an existing application record; and
2796        // (2) The caller doesn't think it is dead, OR there is no thread
2797        //     object attached to it so we know it couldn't have crashed; and
2798        // (3) There is a pid assigned to it, so it is either starting or
2799        //     already running.
2800        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2801                + " app=" + app + " knownToBeDead=" + knownToBeDead
2802                + " thread=" + (app != null ? app.thread : null)
2803                + " pid=" + (app != null ? app.pid : -1));
2804        if (app != null && app.pid > 0) {
2805            if (!knownToBeDead || app.thread == null) {
2806                // We already have the app running, or are waiting for it to
2807                // come up (we have a pid but not yet its thread), so keep it.
2808                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2809                // If this is a new package in the process, add the package to the list
2810                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2811                checkTime(startTime, "startProcess: done, added package to proc");
2812                return app;
2813            }
2814
2815            // An application record is attached to a previous process,
2816            // clean it up now.
2817            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2818            checkTime(startTime, "startProcess: bad proc running, killing");
2819            Process.killProcessGroup(app.info.uid, app.pid);
2820            handleAppDiedLocked(app, true, true);
2821            checkTime(startTime, "startProcess: done killing old proc");
2822        }
2823
2824        String hostingNameStr = hostingName != null
2825                ? hostingName.flattenToShortString() : null;
2826
2827        if (!isolated) {
2828            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2829                // If we are in the background, then check to see if this process
2830                // is bad.  If so, we will just silently fail.
2831                if (mBadProcesses.get(info.processName, info.uid) != null) {
2832                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2833                            + "/" + info.processName);
2834                    return null;
2835                }
2836            } else {
2837                // When the user is explicitly starting a process, then clear its
2838                // crash count so that we won't make it bad until they see at
2839                // least one crash dialog again, and make the process good again
2840                // if it had been bad.
2841                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2842                        + "/" + info.processName);
2843                mProcessCrashTimes.remove(info.processName, info.uid);
2844                if (mBadProcesses.get(info.processName, info.uid) != null) {
2845                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2846                            UserHandle.getUserId(info.uid), info.uid,
2847                            info.processName);
2848                    mBadProcesses.remove(info.processName, info.uid);
2849                    if (app != null) {
2850                        app.bad = false;
2851                    }
2852                }
2853            }
2854        }
2855
2856        if (app == null) {
2857            checkTime(startTime, "startProcess: creating new process record");
2858            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2859            app.crashHandler = crashHandler;
2860            if (app == null) {
2861                Slog.w(TAG, "Failed making new process record for "
2862                        + processName + "/" + info.uid + " isolated=" + isolated);
2863                return null;
2864            }
2865            mProcessNames.put(processName, app.uid, app);
2866            if (isolated) {
2867                mIsolatedProcesses.put(app.uid, app);
2868            }
2869            checkTime(startTime, "startProcess: done creating new process record");
2870        } else {
2871            // If this is a new package in the process, add the package to the list
2872            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2873            checkTime(startTime, "startProcess: added package to existing proc");
2874        }
2875
2876        // If the system is not ready yet, then hold off on starting this
2877        // process until it is.
2878        if (!mProcessesReady
2879                && !isAllowedWhileBooting(info)
2880                && !allowWhileBooting) {
2881            if (!mProcessesOnHold.contains(app)) {
2882                mProcessesOnHold.add(app);
2883            }
2884            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2885            checkTime(startTime, "startProcess: returning with proc on hold");
2886            return app;
2887        }
2888
2889        checkTime(startTime, "startProcess: stepping in to startProcess");
2890        startProcessLocked(
2891                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2892        checkTime(startTime, "startProcess: done starting proc!");
2893        return (app.pid != 0) ? app : null;
2894    }
2895
2896    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2897        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2898    }
2899
2900    private final void startProcessLocked(ProcessRecord app,
2901            String hostingType, String hostingNameStr) {
2902        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2903                null /* entryPoint */, null /* entryPointArgs */);
2904    }
2905
2906    private final void startProcessLocked(ProcessRecord app, String hostingType,
2907            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2908        long startTime = SystemClock.elapsedRealtime();
2909        if (app.pid > 0 && app.pid != MY_PID) {
2910            checkTime(startTime, "startProcess: removing from pids map");
2911            synchronized (mPidsSelfLocked) {
2912                mPidsSelfLocked.remove(app.pid);
2913                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2914            }
2915            checkTime(startTime, "startProcess: done removing from pids map");
2916            app.setPid(0);
2917        }
2918
2919        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2920                "startProcessLocked removing on hold: " + app);
2921        mProcessesOnHold.remove(app);
2922
2923        checkTime(startTime, "startProcess: starting to update cpu stats");
2924        updateCpuStats();
2925        checkTime(startTime, "startProcess: done updating cpu stats");
2926
2927        try {
2928            int uid = app.uid;
2929
2930            int[] gids = null;
2931            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2932            if (!app.isolated) {
2933                int[] permGids = null;
2934                try {
2935                    checkTime(startTime, "startProcess: getting gids from package manager");
2936                    final PackageManager pm = mContext.getPackageManager();
2937                    permGids = pm.getPackageGids(app.info.packageName);
2938
2939                    if (Environment.isExternalStorageEmulated()) {
2940                        checkTime(startTime, "startProcess: checking external storage perm");
2941                        if (pm.checkPermission(
2942                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2943                                app.info.packageName) == PERMISSION_GRANTED) {
2944                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2945                        } else {
2946                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2947                        }
2948                    }
2949                } catch (PackageManager.NameNotFoundException e) {
2950                    Slog.w(TAG, "Unable to retrieve gids", e);
2951                }
2952
2953                /*
2954                 * Add shared application and profile GIDs so applications can share some
2955                 * resources like shared libraries and access user-wide resources
2956                 */
2957                if (permGids == null) {
2958                    gids = new int[2];
2959                } else {
2960                    gids = new int[permGids.length + 2];
2961                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2962                }
2963                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2964                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2965            }
2966            checkTime(startTime, "startProcess: building args");
2967            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2968                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2969                        && mTopComponent != null
2970                        && app.processName.equals(mTopComponent.getPackageName())) {
2971                    uid = 0;
2972                }
2973                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2974                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2975                    uid = 0;
2976                }
2977            }
2978            int debugFlags = 0;
2979            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2980                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2981                // Also turn on CheckJNI for debuggable apps. It's quite
2982                // awkward to turn on otherwise.
2983                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2984            }
2985            // Run the app in safe mode if its manifest requests so or the
2986            // system is booted in safe mode.
2987            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2988                mSafeMode == true) {
2989                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2990            }
2991            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2992                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2993            }
2994            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2995                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2996            }
2997            if ("1".equals(SystemProperties.get("debug.assert"))) {
2998                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2999            }
3000
3001            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3002            if (requiredAbi == null) {
3003                requiredAbi = Build.SUPPORTED_ABIS[0];
3004            }
3005
3006            String instructionSet = null;
3007            if (app.info.primaryCpuAbi != null) {
3008                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3009            }
3010
3011            // Start the process.  It will either succeed and return a result containing
3012            // the PID of the new process, or else throw a RuntimeException.
3013            boolean isActivityProcess = (entryPoint == null);
3014            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3015            checkTime(startTime, "startProcess: asking zygote to start proc");
3016            Process.ProcessStartResult startResult = Process.start(entryPoint,
3017                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3018                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3019                    app.info.dataDir, entryPointArgs);
3020            checkTime(startTime, "startProcess: returned from zygote!");
3021
3022            if (app.isolated) {
3023                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3024            }
3025            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3026            checkTime(startTime, "startProcess: done updating battery stats");
3027
3028            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3029                    UserHandle.getUserId(uid), startResult.pid, uid,
3030                    app.processName, hostingType,
3031                    hostingNameStr != null ? hostingNameStr : "");
3032
3033            if (app.persistent) {
3034                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3035            }
3036
3037            checkTime(startTime, "startProcess: building log message");
3038            StringBuilder buf = mStringBuilder;
3039            buf.setLength(0);
3040            buf.append("Start proc ");
3041            buf.append(app.processName);
3042            if (!isActivityProcess) {
3043                buf.append(" [");
3044                buf.append(entryPoint);
3045                buf.append("]");
3046            }
3047            buf.append(" for ");
3048            buf.append(hostingType);
3049            if (hostingNameStr != null) {
3050                buf.append(" ");
3051                buf.append(hostingNameStr);
3052            }
3053            buf.append(": pid=");
3054            buf.append(startResult.pid);
3055            buf.append(" uid=");
3056            buf.append(uid);
3057            buf.append(" gids={");
3058            if (gids != null) {
3059                for (int gi=0; gi<gids.length; gi++) {
3060                    if (gi != 0) buf.append(", ");
3061                    buf.append(gids[gi]);
3062
3063                }
3064            }
3065            buf.append("}");
3066            if (requiredAbi != null) {
3067                buf.append(" abi=");
3068                buf.append(requiredAbi);
3069            }
3070            Slog.i(TAG, buf.toString());
3071            app.setPid(startResult.pid);
3072            app.usingWrapper = startResult.usingWrapper;
3073            app.removed = false;
3074            app.killed = false;
3075            app.killedByAm = false;
3076            checkTime(startTime, "startProcess: starting to update pids map");
3077            synchronized (mPidsSelfLocked) {
3078                this.mPidsSelfLocked.put(startResult.pid, app);
3079                if (isActivityProcess) {
3080                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3081                    msg.obj = app;
3082                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3083                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3084                }
3085            }
3086            checkTime(startTime, "startProcess: done updating pids map");
3087        } catch (RuntimeException e) {
3088            // XXX do better error recovery.
3089            app.setPid(0);
3090            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3091            if (app.isolated) {
3092                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3093            }
3094            Slog.e(TAG, "Failure starting process " + app.processName, e);
3095        }
3096    }
3097
3098    void updateUsageStats(ActivityRecord component, boolean resumed) {
3099        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3100        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3101        if (resumed) {
3102            if (mUsageStatsService != null) {
3103                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3104                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3105            }
3106            synchronized (stats) {
3107                stats.noteActivityResumedLocked(component.app.uid);
3108            }
3109        } else {
3110            if (mUsageStatsService != null) {
3111                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3112                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3113            }
3114            synchronized (stats) {
3115                stats.noteActivityPausedLocked(component.app.uid);
3116            }
3117        }
3118    }
3119
3120    Intent getHomeIntent() {
3121        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3122        intent.setComponent(mTopComponent);
3123        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3124            intent.addCategory(Intent.CATEGORY_HOME);
3125        }
3126        return intent;
3127    }
3128
3129    boolean startHomeActivityLocked(int userId) {
3130        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3131                && mTopAction == null) {
3132            // We are running in factory test mode, but unable to find
3133            // the factory test app, so just sit around displaying the
3134            // error message and don't try to start anything.
3135            return false;
3136        }
3137        Intent intent = getHomeIntent();
3138        ActivityInfo aInfo =
3139            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3140        if (aInfo != null) {
3141            intent.setComponent(new ComponentName(
3142                    aInfo.applicationInfo.packageName, aInfo.name));
3143            // Don't do this if the home app is currently being
3144            // instrumented.
3145            aInfo = new ActivityInfo(aInfo);
3146            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3147            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3148                    aInfo.applicationInfo.uid, true);
3149            if (app == null || app.instrumentationClass == null) {
3150                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3151                mStackSupervisor.startHomeActivity(intent, aInfo);
3152            }
3153        }
3154
3155        return true;
3156    }
3157
3158    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3159        ActivityInfo ai = null;
3160        ComponentName comp = intent.getComponent();
3161        try {
3162            if (comp != null) {
3163                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3164            } else {
3165                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3166                        intent,
3167                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3168                            flags, userId);
3169
3170                if (info != null) {
3171                    ai = info.activityInfo;
3172                }
3173            }
3174        } catch (RemoteException e) {
3175            // ignore
3176        }
3177
3178        return ai;
3179    }
3180
3181    /**
3182     * Starts the "new version setup screen" if appropriate.
3183     */
3184    void startSetupActivityLocked() {
3185        // Only do this once per boot.
3186        if (mCheckedForSetup) {
3187            return;
3188        }
3189
3190        // We will show this screen if the current one is a different
3191        // version than the last one shown, and we are not running in
3192        // low-level factory test mode.
3193        final ContentResolver resolver = mContext.getContentResolver();
3194        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3195                Settings.Global.getInt(resolver,
3196                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3197            mCheckedForSetup = true;
3198
3199            // See if we should be showing the platform update setup UI.
3200            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3201            List<ResolveInfo> ris = mContext.getPackageManager()
3202                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3203
3204            // We don't allow third party apps to replace this.
3205            ResolveInfo ri = null;
3206            for (int i=0; ris != null && i<ris.size(); i++) {
3207                if ((ris.get(i).activityInfo.applicationInfo.flags
3208                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3209                    ri = ris.get(i);
3210                    break;
3211                }
3212            }
3213
3214            if (ri != null) {
3215                String vers = ri.activityInfo.metaData != null
3216                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3217                        : null;
3218                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3219                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3220                            Intent.METADATA_SETUP_VERSION);
3221                }
3222                String lastVers = Settings.Secure.getString(
3223                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3224                if (vers != null && !vers.equals(lastVers)) {
3225                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3226                    intent.setComponent(new ComponentName(
3227                            ri.activityInfo.packageName, ri.activityInfo.name));
3228                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3229                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3230                            null);
3231                }
3232            }
3233        }
3234    }
3235
3236    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3237        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3238    }
3239
3240    void enforceNotIsolatedCaller(String caller) {
3241        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3242            throw new SecurityException("Isolated process not allowed to call " + caller);
3243        }
3244    }
3245
3246    void enforceShellRestriction(String restriction, int userHandle) {
3247        if (Binder.getCallingUid() == Process.SHELL_UID) {
3248            if (userHandle < 0
3249                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3250                throw new SecurityException("Shell does not have permission to access user "
3251                        + userHandle);
3252            }
3253        }
3254    }
3255
3256    @Override
3257    public int getFrontActivityScreenCompatMode() {
3258        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3259        synchronized (this) {
3260            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3261        }
3262    }
3263
3264    @Override
3265    public void setFrontActivityScreenCompatMode(int mode) {
3266        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3267                "setFrontActivityScreenCompatMode");
3268        synchronized (this) {
3269            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3270        }
3271    }
3272
3273    @Override
3274    public int getPackageScreenCompatMode(String packageName) {
3275        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3276        synchronized (this) {
3277            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3278        }
3279    }
3280
3281    @Override
3282    public void setPackageScreenCompatMode(String packageName, int mode) {
3283        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3284                "setPackageScreenCompatMode");
3285        synchronized (this) {
3286            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3287        }
3288    }
3289
3290    @Override
3291    public boolean getPackageAskScreenCompat(String packageName) {
3292        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3293        synchronized (this) {
3294            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3295        }
3296    }
3297
3298    @Override
3299    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3300        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3301                "setPackageAskScreenCompat");
3302        synchronized (this) {
3303            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3304        }
3305    }
3306
3307    private void dispatchProcessesChanged() {
3308        int N;
3309        synchronized (this) {
3310            N = mPendingProcessChanges.size();
3311            if (mActiveProcessChanges.length < N) {
3312                mActiveProcessChanges = new ProcessChangeItem[N];
3313            }
3314            mPendingProcessChanges.toArray(mActiveProcessChanges);
3315            mAvailProcessChanges.addAll(mPendingProcessChanges);
3316            mPendingProcessChanges.clear();
3317            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3318        }
3319
3320        int i = mProcessObservers.beginBroadcast();
3321        while (i > 0) {
3322            i--;
3323            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3324            if (observer != null) {
3325                try {
3326                    for (int j=0; j<N; j++) {
3327                        ProcessChangeItem item = mActiveProcessChanges[j];
3328                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3329                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3330                                    + item.pid + " uid=" + item.uid + ": "
3331                                    + item.foregroundActivities);
3332                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3333                                    item.foregroundActivities);
3334                        }
3335                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3336                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3337                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3338                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3339                        }
3340                    }
3341                } catch (RemoteException e) {
3342                }
3343            }
3344        }
3345        mProcessObservers.finishBroadcast();
3346    }
3347
3348    private void dispatchProcessDied(int pid, int uid) {
3349        int i = mProcessObservers.beginBroadcast();
3350        while (i > 0) {
3351            i--;
3352            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3353            if (observer != null) {
3354                try {
3355                    observer.onProcessDied(pid, uid);
3356                } catch (RemoteException e) {
3357                }
3358            }
3359        }
3360        mProcessObservers.finishBroadcast();
3361    }
3362
3363    @Override
3364    public final int startActivity(IApplicationThread caller, String callingPackage,
3365            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3366            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3367        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3368            resultWho, requestCode, startFlags, profilerInfo, options,
3369            UserHandle.getCallingUserId());
3370    }
3371
3372    @Override
3373    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3374            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3375            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3376        enforceNotIsolatedCaller("startActivity");
3377        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3378                false, ALLOW_FULL_ONLY, "startActivity", null);
3379        // TODO: Switch to user app stacks here.
3380        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3381                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3382                profilerInfo, null, null, options, userId, null, null);
3383    }
3384
3385    @Override
3386    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3387            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3388            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3389
3390        // This is very dangerous -- it allows you to perform a start activity (including
3391        // permission grants) as any app that may launch one of your own activities.  So
3392        // we will only allow this to be done from activities that are part of the core framework,
3393        // and then only when they are running as the system.
3394        final ActivityRecord sourceRecord;
3395        final int targetUid;
3396        final String targetPackage;
3397        synchronized (this) {
3398            if (resultTo == null) {
3399                throw new SecurityException("Must be called from an activity");
3400            }
3401            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3402            if (sourceRecord == null) {
3403                throw new SecurityException("Called with bad activity token: " + resultTo);
3404            }
3405            if (!sourceRecord.info.packageName.equals("android")) {
3406                throw new SecurityException(
3407                        "Must be called from an activity that is declared in the android package");
3408            }
3409            if (sourceRecord.app == null) {
3410                throw new SecurityException("Called without a process attached to activity");
3411            }
3412            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3413                // This is still okay, as long as this activity is running under the
3414                // uid of the original calling activity.
3415                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3416                    throw new SecurityException(
3417                            "Calling activity in uid " + sourceRecord.app.uid
3418                                    + " must be system uid or original calling uid "
3419                                    + sourceRecord.launchedFromUid);
3420                }
3421            }
3422            targetUid = sourceRecord.launchedFromUid;
3423            targetPackage = sourceRecord.launchedFromPackage;
3424        }
3425
3426        if (userId == UserHandle.USER_NULL) {
3427            userId = UserHandle.getUserId(sourceRecord.app.uid);
3428        }
3429
3430        // TODO: Switch to user app stacks here.
3431        try {
3432            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3433                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3434                    null, null, options, userId, null, null);
3435            return ret;
3436        } catch (SecurityException e) {
3437            // XXX need to figure out how to propagate to original app.
3438            // A SecurityException here is generally actually a fault of the original
3439            // calling activity (such as a fairly granting permissions), so propagate it
3440            // back to them.
3441            /*
3442            StringBuilder msg = new StringBuilder();
3443            msg.append("While launching");
3444            msg.append(intent.toString());
3445            msg.append(": ");
3446            msg.append(e.getMessage());
3447            */
3448            throw e;
3449        }
3450    }
3451
3452    @Override
3453    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3454            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3455            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3456        enforceNotIsolatedCaller("startActivityAndWait");
3457        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3458                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3459        WaitResult res = new WaitResult();
3460        // TODO: Switch to user app stacks here.
3461        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3462                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3463                options, userId, null, null);
3464        return res;
3465    }
3466
3467    @Override
3468    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3469            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3470            int startFlags, Configuration config, Bundle options, int userId) {
3471        enforceNotIsolatedCaller("startActivityWithConfig");
3472        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3473                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3474        // TODO: Switch to user app stacks here.
3475        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3476                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3477                null, null, config, options, userId, null, null);
3478        return ret;
3479    }
3480
3481    @Override
3482    public int startActivityIntentSender(IApplicationThread caller,
3483            IntentSender intent, Intent fillInIntent, String resolvedType,
3484            IBinder resultTo, String resultWho, int requestCode,
3485            int flagsMask, int flagsValues, Bundle options) {
3486        enforceNotIsolatedCaller("startActivityIntentSender");
3487        // Refuse possible leaked file descriptors
3488        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3489            throw new IllegalArgumentException("File descriptors passed in Intent");
3490        }
3491
3492        IIntentSender sender = intent.getTarget();
3493        if (!(sender instanceof PendingIntentRecord)) {
3494            throw new IllegalArgumentException("Bad PendingIntent object");
3495        }
3496
3497        PendingIntentRecord pir = (PendingIntentRecord)sender;
3498
3499        synchronized (this) {
3500            // If this is coming from the currently resumed activity, it is
3501            // effectively saying that app switches are allowed at this point.
3502            final ActivityStack stack = getFocusedStack();
3503            if (stack.mResumedActivity != null &&
3504                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3505                mAppSwitchesAllowedTime = 0;
3506            }
3507        }
3508        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3509                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3510        return ret;
3511    }
3512
3513    @Override
3514    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3515            Intent intent, String resolvedType, IVoiceInteractionSession session,
3516            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3517            Bundle options, int userId) {
3518        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3519                != PackageManager.PERMISSION_GRANTED) {
3520            String msg = "Permission Denial: startVoiceActivity() from pid="
3521                    + Binder.getCallingPid()
3522                    + ", uid=" + Binder.getCallingUid()
3523                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3524            Slog.w(TAG, msg);
3525            throw new SecurityException(msg);
3526        }
3527        if (session == null || interactor == null) {
3528            throw new NullPointerException("null session or interactor");
3529        }
3530        userId = handleIncomingUser(callingPid, callingUid, userId,
3531                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3532        // TODO: Switch to user app stacks here.
3533        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3534                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3535                null, options, userId, null, null);
3536    }
3537
3538    @Override
3539    public boolean startNextMatchingActivity(IBinder callingActivity,
3540            Intent intent, Bundle options) {
3541        // Refuse possible leaked file descriptors
3542        if (intent != null && intent.hasFileDescriptors() == true) {
3543            throw new IllegalArgumentException("File descriptors passed in Intent");
3544        }
3545
3546        synchronized (this) {
3547            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3548            if (r == null) {
3549                ActivityOptions.abort(options);
3550                return false;
3551            }
3552            if (r.app == null || r.app.thread == null) {
3553                // The caller is not running...  d'oh!
3554                ActivityOptions.abort(options);
3555                return false;
3556            }
3557            intent = new Intent(intent);
3558            // The caller is not allowed to change the data.
3559            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3560            // And we are resetting to find the next component...
3561            intent.setComponent(null);
3562
3563            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3564
3565            ActivityInfo aInfo = null;
3566            try {
3567                List<ResolveInfo> resolves =
3568                    AppGlobals.getPackageManager().queryIntentActivities(
3569                            intent, r.resolvedType,
3570                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3571                            UserHandle.getCallingUserId());
3572
3573                // Look for the original activity in the list...
3574                final int N = resolves != null ? resolves.size() : 0;
3575                for (int i=0; i<N; i++) {
3576                    ResolveInfo rInfo = resolves.get(i);
3577                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3578                            && rInfo.activityInfo.name.equals(r.info.name)) {
3579                        // We found the current one...  the next matching is
3580                        // after it.
3581                        i++;
3582                        if (i<N) {
3583                            aInfo = resolves.get(i).activityInfo;
3584                        }
3585                        if (debug) {
3586                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3587                                    + "/" + r.info.name);
3588                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3589                                    + "/" + aInfo.name);
3590                        }
3591                        break;
3592                    }
3593                }
3594            } catch (RemoteException e) {
3595            }
3596
3597            if (aInfo == null) {
3598                // Nobody who is next!
3599                ActivityOptions.abort(options);
3600                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3601                return false;
3602            }
3603
3604            intent.setComponent(new ComponentName(
3605                    aInfo.applicationInfo.packageName, aInfo.name));
3606            intent.setFlags(intent.getFlags()&~(
3607                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3608                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3609                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3610                    Intent.FLAG_ACTIVITY_NEW_TASK));
3611
3612            // Okay now we need to start the new activity, replacing the
3613            // currently running activity.  This is a little tricky because
3614            // we want to start the new one as if the current one is finished,
3615            // but not finish the current one first so that there is no flicker.
3616            // And thus...
3617            final boolean wasFinishing = r.finishing;
3618            r.finishing = true;
3619
3620            // Propagate reply information over to the new activity.
3621            final ActivityRecord resultTo = r.resultTo;
3622            final String resultWho = r.resultWho;
3623            final int requestCode = r.requestCode;
3624            r.resultTo = null;
3625            if (resultTo != null) {
3626                resultTo.removeResultsLocked(r, resultWho, requestCode);
3627            }
3628
3629            final long origId = Binder.clearCallingIdentity();
3630            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3631                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3632                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3633                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3634            Binder.restoreCallingIdentity(origId);
3635
3636            r.finishing = wasFinishing;
3637            if (res != ActivityManager.START_SUCCESS) {
3638                return false;
3639            }
3640            return true;
3641        }
3642    }
3643
3644    @Override
3645    public final int startActivityFromRecents(int taskId, Bundle options) {
3646        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3647            String msg = "Permission Denial: startActivityFromRecents called without " +
3648                    START_TASKS_FROM_RECENTS;
3649            Slog.w(TAG, msg);
3650            throw new SecurityException(msg);
3651        }
3652        return startActivityFromRecentsInner(taskId, options);
3653    }
3654
3655    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3656        final TaskRecord task;
3657        final int callingUid;
3658        final String callingPackage;
3659        final Intent intent;
3660        final int userId;
3661        synchronized (this) {
3662            task = recentTaskForIdLocked(taskId);
3663            if (task == null) {
3664                throw new IllegalArgumentException("Task " + taskId + " not found.");
3665            }
3666            callingUid = task.mCallingUid;
3667            callingPackage = task.mCallingPackage;
3668            intent = task.intent;
3669            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3670            userId = task.userId;
3671        }
3672        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3673                options, userId, null, task);
3674    }
3675
3676    final int startActivityInPackage(int uid, String callingPackage,
3677            Intent intent, String resolvedType, IBinder resultTo,
3678            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3679            IActivityContainer container, TaskRecord inTask) {
3680
3681        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3682                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3683
3684        // TODO: Switch to user app stacks here.
3685        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3686                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3687                null, null, null, options, userId, container, inTask);
3688        return ret;
3689    }
3690
3691    @Override
3692    public final int startActivities(IApplicationThread caller, String callingPackage,
3693            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3694            int userId) {
3695        enforceNotIsolatedCaller("startActivities");
3696        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3697                false, ALLOW_FULL_ONLY, "startActivity", null);
3698        // TODO: Switch to user app stacks here.
3699        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3700                resolvedTypes, resultTo, options, userId);
3701        return ret;
3702    }
3703
3704    final int startActivitiesInPackage(int uid, String callingPackage,
3705            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3706            Bundle options, int userId) {
3707
3708        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3709                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3710        // TODO: Switch to user app stacks here.
3711        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3712                resultTo, options, userId);
3713        return ret;
3714    }
3715
3716    //explicitly remove thd old information in mRecentTasks when removing existing user.
3717    private void removeRecentTasksForUserLocked(int userId) {
3718        if(userId <= 0) {
3719            Slog.i(TAG, "Can't remove recent task on user " + userId);
3720            return;
3721        }
3722
3723        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3724            TaskRecord tr = mRecentTasks.get(i);
3725            if (tr.userId == userId) {
3726                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3727                        + " when finishing user" + userId);
3728                mRecentTasks.remove(i);
3729                tr.removedFromRecents(mTaskPersister);
3730            }
3731        }
3732
3733        // Remove tasks from persistent storage.
3734        mTaskPersister.wakeup(null, true);
3735    }
3736
3737    // Sort by taskId
3738    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3739        @Override
3740        public int compare(TaskRecord lhs, TaskRecord rhs) {
3741            return rhs.taskId - lhs.taskId;
3742        }
3743    };
3744
3745    // Extract the affiliates of the chain containing mRecentTasks[start].
3746    private int processNextAffiliateChain(int start) {
3747        final TaskRecord startTask = mRecentTasks.get(start);
3748        final int affiliateId = startTask.mAffiliatedTaskId;
3749
3750        // Quick identification of isolated tasks. I.e. those not launched behind.
3751        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3752                startTask.mNextAffiliate == null) {
3753            // There is still a slim chance that there are other tasks that point to this task
3754            // and that the chain is so messed up that this task no longer points to them but
3755            // the gain of this optimization outweighs the risk.
3756            startTask.inRecents = true;
3757            return start + 1;
3758        }
3759
3760        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3761        mTmpRecents.clear();
3762        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3763            final TaskRecord task = mRecentTasks.get(i);
3764            if (task.mAffiliatedTaskId == affiliateId) {
3765                mRecentTasks.remove(i);
3766                mTmpRecents.add(task);
3767            }
3768        }
3769
3770        // Sort them all by taskId. That is the order they were create in and that order will
3771        // always be correct.
3772        Collections.sort(mTmpRecents, mTaskRecordComparator);
3773
3774        // Go through and fix up the linked list.
3775        // The first one is the end of the chain and has no next.
3776        final TaskRecord first = mTmpRecents.get(0);
3777        first.inRecents = true;
3778        if (first.mNextAffiliate != null) {
3779            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3780            first.setNextAffiliate(null);
3781            mTaskPersister.wakeup(first, false);
3782        }
3783        // Everything in the middle is doubly linked from next to prev.
3784        final int tmpSize = mTmpRecents.size();
3785        for (int i = 0; i < tmpSize - 1; ++i) {
3786            final TaskRecord next = mTmpRecents.get(i);
3787            final TaskRecord prev = mTmpRecents.get(i + 1);
3788            if (next.mPrevAffiliate != prev) {
3789                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3790                        " setting prev=" + prev);
3791                next.setPrevAffiliate(prev);
3792                mTaskPersister.wakeup(next, false);
3793            }
3794            if (prev.mNextAffiliate != next) {
3795                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3796                        " setting next=" + next);
3797                prev.setNextAffiliate(next);
3798                mTaskPersister.wakeup(prev, false);
3799            }
3800            prev.inRecents = true;
3801        }
3802        // The last one is the beginning of the list and has no prev.
3803        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3804        if (last.mPrevAffiliate != null) {
3805            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3806            last.setPrevAffiliate(null);
3807            mTaskPersister.wakeup(last, false);
3808        }
3809
3810        // Insert the group back into mRecentTasks at start.
3811        mRecentTasks.addAll(start, mTmpRecents);
3812
3813        // Let the caller know where we left off.
3814        return start + tmpSize;
3815    }
3816
3817    /**
3818     * Update the recent tasks lists: make sure tasks should still be here (their
3819     * applications / activities still exist), update their availability, fixup ordering
3820     * of affiliations.
3821     */
3822    void cleanupRecentTasksLocked(int userId) {
3823        if (mRecentTasks == null) {
3824            // Happens when called from the packagemanager broadcast before boot.
3825            return;
3826        }
3827
3828        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3829        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3830        final IPackageManager pm = AppGlobals.getPackageManager();
3831        final ActivityInfo dummyAct = new ActivityInfo();
3832        final ApplicationInfo dummyApp = new ApplicationInfo();
3833
3834        int N = mRecentTasks.size();
3835
3836        int[] users = userId == UserHandle.USER_ALL
3837                ? getUsersLocked() : new int[] { userId };
3838        for (int user : users) {
3839            for (int i = 0; i < N; i++) {
3840                TaskRecord task = mRecentTasks.get(i);
3841                if (task.userId != user) {
3842                    // Only look at tasks for the user ID of interest.
3843                    continue;
3844                }
3845                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3846                    // This situation is broken, and we should just get rid of it now.
3847                    mRecentTasks.remove(i);
3848                    task.removedFromRecents(mTaskPersister);
3849                    i--;
3850                    N--;
3851                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3852                    continue;
3853                }
3854                // Check whether this activity is currently available.
3855                if (task.realActivity != null) {
3856                    ActivityInfo ai = availActCache.get(task.realActivity);
3857                    if (ai == null) {
3858                        try {
3859                            ai = pm.getActivityInfo(task.realActivity,
3860                                    PackageManager.GET_UNINSTALLED_PACKAGES
3861                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3862                        } catch (RemoteException e) {
3863                            // Will never happen.
3864                            continue;
3865                        }
3866                        if (ai == null) {
3867                            ai = dummyAct;
3868                        }
3869                        availActCache.put(task.realActivity, ai);
3870                    }
3871                    if (ai == dummyAct) {
3872                        // This could be either because the activity no longer exists, or the
3873                        // app is temporarily gone.  For the former we want to remove the recents
3874                        // entry; for the latter we want to mark it as unavailable.
3875                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3876                        if (app == null) {
3877                            try {
3878                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3879                                        PackageManager.GET_UNINSTALLED_PACKAGES
3880                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3881                            } catch (RemoteException e) {
3882                                // Will never happen.
3883                                continue;
3884                            }
3885                            if (app == null) {
3886                                app = dummyApp;
3887                            }
3888                            availAppCache.put(task.realActivity.getPackageName(), app);
3889                        }
3890                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3891                            // Doesn't exist any more!  Good-bye.
3892                            mRecentTasks.remove(i);
3893                            task.removedFromRecents(mTaskPersister);
3894                            i--;
3895                            N--;
3896                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3897                            continue;
3898                        } else {
3899                            // Otherwise just not available for now.
3900                            if (task.isAvailable) {
3901                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3902                                        + task);
3903                            }
3904                            task.isAvailable = false;
3905                        }
3906                    } else {
3907                        if (!ai.enabled || !ai.applicationInfo.enabled
3908                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3909                            if (task.isAvailable) {
3910                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3911                                        + task + " (enabled=" + ai.enabled + "/"
3912                                        + ai.applicationInfo.enabled +  " flags="
3913                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3914                            }
3915                            task.isAvailable = false;
3916                        } else {
3917                            if (!task.isAvailable) {
3918                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3919                                        + task);
3920                            }
3921                            task.isAvailable = true;
3922                        }
3923                    }
3924                }
3925            }
3926        }
3927
3928        // Verify the affiliate chain for each task.
3929        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
3930        }
3931
3932        mTmpRecents.clear();
3933        // mRecentTasks is now in sorted, affiliated order.
3934    }
3935
3936    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3937        int N = mRecentTasks.size();
3938        TaskRecord top = task;
3939        int topIndex = taskIndex;
3940        while (top.mNextAffiliate != null && topIndex > 0) {
3941            top = top.mNextAffiliate;
3942            topIndex--;
3943        }
3944        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3945                + topIndex + " from intial " + taskIndex);
3946        // Find the end of the chain, doing a sanity check along the way.
3947        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3948        int endIndex = topIndex;
3949        TaskRecord prev = top;
3950        while (endIndex < N) {
3951            TaskRecord cur = mRecentTasks.get(endIndex);
3952            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3953                    + endIndex + " " + cur);
3954            if (cur == top) {
3955                // Verify start of the chain.
3956                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3957                    Slog.wtf(TAG, "Bad chain @" + endIndex
3958                            + ": first task has next affiliate: " + prev);
3959                    sane = false;
3960                    break;
3961                }
3962            } else {
3963                // Verify middle of the chain's next points back to the one before.
3964                if (cur.mNextAffiliate != prev
3965                        || cur.mNextAffiliateTaskId != prev.taskId) {
3966                    Slog.wtf(TAG, "Bad chain @" + endIndex
3967                            + ": middle task " + cur + " @" + endIndex
3968                            + " has bad next affiliate "
3969                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3970                            + ", expected " + prev);
3971                    sane = false;
3972                    break;
3973                }
3974            }
3975            if (cur.mPrevAffiliateTaskId == -1) {
3976                // Chain ends here.
3977                if (cur.mPrevAffiliate != null) {
3978                    Slog.wtf(TAG, "Bad chain @" + endIndex
3979                            + ": last task " + cur + " has previous affiliate "
3980                            + cur.mPrevAffiliate);
3981                    sane = false;
3982                }
3983                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3984                break;
3985            } else {
3986                // Verify middle of the chain's prev points to a valid item.
3987                if (cur.mPrevAffiliate == null) {
3988                    Slog.wtf(TAG, "Bad chain @" + endIndex
3989                            + ": task " + cur + " has previous affiliate "
3990                            + cur.mPrevAffiliate + " but should be id "
3991                            + cur.mPrevAffiliate);
3992                    sane = false;
3993                    break;
3994                }
3995            }
3996            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3997                Slog.wtf(TAG, "Bad chain @" + endIndex
3998                        + ": task " + cur + " has affiliated id "
3999                        + cur.mAffiliatedTaskId + " but should be "
4000                        + task.mAffiliatedTaskId);
4001                sane = false;
4002                break;
4003            }
4004            prev = cur;
4005            endIndex++;
4006            if (endIndex >= N) {
4007                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4008                        + ": last task " + prev);
4009                sane = false;
4010                break;
4011            }
4012        }
4013        if (sane) {
4014            if (endIndex < taskIndex) {
4015                Slog.wtf(TAG, "Bad chain @" + endIndex
4016                        + ": did not extend to task " + task + " @" + taskIndex);
4017                sane = false;
4018            }
4019        }
4020        if (sane) {
4021            // All looks good, we can just move all of the affiliated tasks
4022            // to the top.
4023            for (int i=topIndex; i<=endIndex; i++) {
4024                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4025                        + " from " + i + " to " + (i-topIndex));
4026                TaskRecord cur = mRecentTasks.remove(i);
4027                mRecentTasks.add(i-topIndex, cur);
4028            }
4029            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4030                    + " to " + endIndex);
4031            return true;
4032        }
4033
4034        // Whoops, couldn't do it.
4035        return false;
4036    }
4037
4038    final void addRecentTaskLocked(TaskRecord task) {
4039        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4040                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4041
4042        int N = mRecentTasks.size();
4043        // Quick case: check if the top-most recent task is the same.
4044        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4045            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4046            return;
4047        }
4048        // Another quick case: check if this is part of a set of affiliated
4049        // tasks that are at the top.
4050        if (isAffiliated && N > 0 && task.inRecents
4051                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4052            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4053                    + " at top when adding " + task);
4054            return;
4055        }
4056        // Another quick case: never add voice sessions.
4057        if (task.voiceSession != null) {
4058            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4059            return;
4060        }
4061
4062        boolean needAffiliationFix = false;
4063
4064        // Slightly less quick case: the task is already in recents, so all we need
4065        // to do is move it.
4066        if (task.inRecents) {
4067            int taskIndex = mRecentTasks.indexOf(task);
4068            if (taskIndex >= 0) {
4069                if (!isAffiliated) {
4070                    // Simple case: this is not an affiliated task, so we just move it to the front.
4071                    mRecentTasks.remove(taskIndex);
4072                    mRecentTasks.add(0, task);
4073                    notifyTaskPersisterLocked(task, false);
4074                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4075                            + " from " + taskIndex);
4076                    return;
4077                } else {
4078                    // More complicated: need to keep all affiliated tasks together.
4079                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4080                        // All went well.
4081                        return;
4082                    }
4083
4084                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4085                    // everything and then go through our general path of adding a new task.
4086                    needAffiliationFix = true;
4087                }
4088            } else {
4089                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4090                needAffiliationFix = true;
4091            }
4092        }
4093
4094        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4095        trimRecentsForTask(task, true);
4096
4097        N = mRecentTasks.size();
4098        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4099            final TaskRecord tr = mRecentTasks.remove(N - 1);
4100            tr.removedFromRecents(mTaskPersister);
4101            N--;
4102        }
4103        task.inRecents = true;
4104        if (!isAffiliated || needAffiliationFix) {
4105            // If this is a simple non-affiliated task, or we had some failure trying to
4106            // handle it as part of an affilated task, then just place it at the top.
4107            mRecentTasks.add(0, task);
4108        } else if (isAffiliated) {
4109            // If this is a new affiliated task, then move all of the affiliated tasks
4110            // to the front and insert this new one.
4111            TaskRecord other = task.mNextAffiliate;
4112            if (other == null) {
4113                other = task.mPrevAffiliate;
4114            }
4115            if (other != null) {
4116                int otherIndex = mRecentTasks.indexOf(other);
4117                if (otherIndex >= 0) {
4118                    // Insert new task at appropriate location.
4119                    int taskIndex;
4120                    if (other == task.mNextAffiliate) {
4121                        // We found the index of our next affiliation, which is who is
4122                        // before us in the list, so add after that point.
4123                        taskIndex = otherIndex+1;
4124                    } else {
4125                        // We found the index of our previous affiliation, which is who is
4126                        // after us in the list, so add at their position.
4127                        taskIndex = otherIndex;
4128                    }
4129                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4130                            + taskIndex + ": " + task);
4131                    mRecentTasks.add(taskIndex, task);
4132
4133                    // Now move everything to the front.
4134                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4135                        // All went well.
4136                        return;
4137                    }
4138
4139                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4140                    // everything and then go through our general path of adding a new task.
4141                    needAffiliationFix = true;
4142                } else {
4143                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4144                            + other);
4145                    needAffiliationFix = true;
4146                }
4147            } else {
4148                if (DEBUG_RECENTS) Slog.d(TAG,
4149                        "addRecent: adding affiliated task without next/prev:" + task);
4150                needAffiliationFix = true;
4151            }
4152        }
4153        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4154
4155        if (needAffiliationFix) {
4156            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4157            cleanupRecentTasksLocked(task.userId);
4158        }
4159    }
4160
4161    /**
4162     * If needed, remove oldest existing entries in recents that are for the same kind
4163     * of task as the given one.
4164     */
4165    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4166        int N = mRecentTasks.size();
4167        final Intent intent = task.intent;
4168        final boolean document = intent != null && intent.isDocument();
4169
4170        int maxRecents = task.maxRecents - 1;
4171        for (int i=0; i<N; i++) {
4172            final TaskRecord tr = mRecentTasks.get(i);
4173            if (task != tr) {
4174                if (task.userId != tr.userId) {
4175                    continue;
4176                }
4177                if (i > MAX_RECENT_BITMAPS) {
4178                    tr.freeLastThumbnail();
4179                }
4180                final Intent trIntent = tr.intent;
4181                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4182                    (intent == null || !intent.filterEquals(trIntent))) {
4183                    continue;
4184                }
4185                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4186                if (document && trIsDocument) {
4187                    // These are the same document activity (not necessarily the same doc).
4188                    if (maxRecents > 0) {
4189                        --maxRecents;
4190                        continue;
4191                    }
4192                    // Hit the maximum number of documents for this task. Fall through
4193                    // and remove this document from recents.
4194                } else if (document || trIsDocument) {
4195                    // Only one of these is a document. Not the droid we're looking for.
4196                    continue;
4197                }
4198            }
4199
4200            if (!doTrim) {
4201                // If the caller is not actually asking for a trim, just tell them we reached
4202                // a point where the trim would happen.
4203                return i;
4204            }
4205
4206            // Either task and tr are the same or, their affinities match or their intents match
4207            // and neither of them is a document, or they are documents using the same activity
4208            // and their maxRecents has been reached.
4209            tr.disposeThumbnail();
4210            mRecentTasks.remove(i);
4211            if (task != tr) {
4212                tr.removedFromRecents(mTaskPersister);
4213            }
4214            i--;
4215            N--;
4216            if (task.intent == null) {
4217                // If the new recent task we are adding is not fully
4218                // specified, then replace it with the existing recent task.
4219                task = tr;
4220            }
4221            notifyTaskPersisterLocked(tr, false);
4222        }
4223
4224        return -1;
4225    }
4226
4227    @Override
4228    public void reportActivityFullyDrawn(IBinder token) {
4229        synchronized (this) {
4230            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4231            if (r == null) {
4232                return;
4233            }
4234            r.reportFullyDrawnLocked();
4235        }
4236    }
4237
4238    @Override
4239    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4240        synchronized (this) {
4241            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4242            if (r == null) {
4243                return;
4244            }
4245            final long origId = Binder.clearCallingIdentity();
4246            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4247            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4248                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4249            if (config != null) {
4250                r.frozenBeforeDestroy = true;
4251                if (!updateConfigurationLocked(config, r, false, false)) {
4252                    mStackSupervisor.resumeTopActivitiesLocked();
4253                }
4254            }
4255            Binder.restoreCallingIdentity(origId);
4256        }
4257    }
4258
4259    @Override
4260    public int getRequestedOrientation(IBinder token) {
4261        synchronized (this) {
4262            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4263            if (r == null) {
4264                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4265            }
4266            return mWindowManager.getAppOrientation(r.appToken);
4267        }
4268    }
4269
4270    /**
4271     * This is the internal entry point for handling Activity.finish().
4272     *
4273     * @param token The Binder token referencing the Activity we want to finish.
4274     * @param resultCode Result code, if any, from this Activity.
4275     * @param resultData Result data (Intent), if any, from this Activity.
4276     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4277     *            the root Activity in the task.
4278     *
4279     * @return Returns true if the activity successfully finished, or false if it is still running.
4280     */
4281    @Override
4282    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4283            boolean finishTask) {
4284        // Refuse possible leaked file descriptors
4285        if (resultData != null && resultData.hasFileDescriptors() == true) {
4286            throw new IllegalArgumentException("File descriptors passed in Intent");
4287        }
4288
4289        synchronized(this) {
4290            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4291            if (r == null) {
4292                return true;
4293            }
4294            // Keep track of the root activity of the task before we finish it
4295            TaskRecord tr = r.task;
4296            ActivityRecord rootR = tr.getRootActivity();
4297            if (rootR == null) {
4298                Slog.w(TAG, "Finishing task with all activities already finished");
4299            }
4300            // Do not allow task to finish in Lock Task mode.
4301            if (tr == mStackSupervisor.mLockTaskModeTask) {
4302                if (rootR == r) {
4303                    Slog.i(TAG, "Not finishing task in lock task mode");
4304                    mStackSupervisor.showLockTaskToast();
4305                    return false;
4306                }
4307            }
4308            if (mController != null) {
4309                // Find the first activity that is not finishing.
4310                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4311                if (next != null) {
4312                    // ask watcher if this is allowed
4313                    boolean resumeOK = true;
4314                    try {
4315                        resumeOK = mController.activityResuming(next.packageName);
4316                    } catch (RemoteException e) {
4317                        mController = null;
4318                        Watchdog.getInstance().setActivityController(null);
4319                    }
4320
4321                    if (!resumeOK) {
4322                        Slog.i(TAG, "Not finishing activity because controller resumed");
4323                        return false;
4324                    }
4325                }
4326            }
4327            final long origId = Binder.clearCallingIdentity();
4328            try {
4329                boolean res;
4330                if (finishTask && r == rootR) {
4331                    // If requested, remove the task that is associated to this activity only if it
4332                    // was the root activity in the task. The result code and data is ignored
4333                    // because we don't support returning them across task boundaries.
4334                    res = removeTaskByIdLocked(tr.taskId, false);
4335                    if (!res) {
4336                        Slog.i(TAG, "Removing task failed to finish activity");
4337                    }
4338                } else {
4339                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4340                            resultData, "app-request", true);
4341                    if (!res) {
4342                        Slog.i(TAG, "Failed to finish by app-request");
4343                    }
4344                }
4345                return res;
4346            } finally {
4347                Binder.restoreCallingIdentity(origId);
4348            }
4349        }
4350    }
4351
4352    @Override
4353    public final void finishHeavyWeightApp() {
4354        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4355                != PackageManager.PERMISSION_GRANTED) {
4356            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4357                    + Binder.getCallingPid()
4358                    + ", uid=" + Binder.getCallingUid()
4359                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4360            Slog.w(TAG, msg);
4361            throw new SecurityException(msg);
4362        }
4363
4364        synchronized(this) {
4365            if (mHeavyWeightProcess == null) {
4366                return;
4367            }
4368
4369            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4370                    mHeavyWeightProcess.activities);
4371            for (int i=0; i<activities.size(); i++) {
4372                ActivityRecord r = activities.get(i);
4373                if (!r.finishing) {
4374                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4375                            null, "finish-heavy", true);
4376                }
4377            }
4378
4379            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4380                    mHeavyWeightProcess.userId, 0));
4381            mHeavyWeightProcess = null;
4382        }
4383    }
4384
4385    @Override
4386    public void crashApplication(int uid, int initialPid, String packageName,
4387            String message) {
4388        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4389                != PackageManager.PERMISSION_GRANTED) {
4390            String msg = "Permission Denial: crashApplication() from pid="
4391                    + Binder.getCallingPid()
4392                    + ", uid=" + Binder.getCallingUid()
4393                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4394            Slog.w(TAG, msg);
4395            throw new SecurityException(msg);
4396        }
4397
4398        synchronized(this) {
4399            ProcessRecord proc = null;
4400
4401            // Figure out which process to kill.  We don't trust that initialPid
4402            // still has any relation to current pids, so must scan through the
4403            // list.
4404            synchronized (mPidsSelfLocked) {
4405                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4406                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4407                    if (p.uid != uid) {
4408                        continue;
4409                    }
4410                    if (p.pid == initialPid) {
4411                        proc = p;
4412                        break;
4413                    }
4414                    if (p.pkgList.containsKey(packageName)) {
4415                        proc = p;
4416                    }
4417                }
4418            }
4419
4420            if (proc == null) {
4421                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4422                        + " initialPid=" + initialPid
4423                        + " packageName=" + packageName);
4424                return;
4425            }
4426
4427            if (proc.thread != null) {
4428                if (proc.pid == Process.myPid()) {
4429                    Log.w(TAG, "crashApplication: trying to crash self!");
4430                    return;
4431                }
4432                long ident = Binder.clearCallingIdentity();
4433                try {
4434                    proc.thread.scheduleCrash(message);
4435                } catch (RemoteException e) {
4436                }
4437                Binder.restoreCallingIdentity(ident);
4438            }
4439        }
4440    }
4441
4442    @Override
4443    public final void finishSubActivity(IBinder token, String resultWho,
4444            int requestCode) {
4445        synchronized(this) {
4446            final long origId = Binder.clearCallingIdentity();
4447            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4448            if (r != null) {
4449                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4450            }
4451            Binder.restoreCallingIdentity(origId);
4452        }
4453    }
4454
4455    @Override
4456    public boolean finishActivityAffinity(IBinder token) {
4457        synchronized(this) {
4458            final long origId = Binder.clearCallingIdentity();
4459            try {
4460                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4461
4462                ActivityRecord rootR = r.task.getRootActivity();
4463                // Do not allow task to finish in Lock Task mode.
4464                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4465                    if (rootR == r) {
4466                        mStackSupervisor.showLockTaskToast();
4467                        return false;
4468                    }
4469                }
4470                boolean res = false;
4471                if (r != null) {
4472                    res = r.task.stack.finishActivityAffinityLocked(r);
4473                }
4474                return res;
4475            } finally {
4476                Binder.restoreCallingIdentity(origId);
4477            }
4478        }
4479    }
4480
4481    @Override
4482    public void finishVoiceTask(IVoiceInteractionSession session) {
4483        synchronized(this) {
4484            final long origId = Binder.clearCallingIdentity();
4485            try {
4486                mStackSupervisor.finishVoiceTask(session);
4487            } finally {
4488                Binder.restoreCallingIdentity(origId);
4489            }
4490        }
4491
4492    }
4493
4494    @Override
4495    public boolean releaseActivityInstance(IBinder token) {
4496        synchronized(this) {
4497            final long origId = Binder.clearCallingIdentity();
4498            try {
4499                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4500                if (r.task == null || r.task.stack == null) {
4501                    return false;
4502                }
4503                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4504            } finally {
4505                Binder.restoreCallingIdentity(origId);
4506            }
4507        }
4508    }
4509
4510    @Override
4511    public void releaseSomeActivities(IApplicationThread appInt) {
4512        synchronized(this) {
4513            final long origId = Binder.clearCallingIdentity();
4514            try {
4515                ProcessRecord app = getRecordForAppLocked(appInt);
4516                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4517            } finally {
4518                Binder.restoreCallingIdentity(origId);
4519            }
4520        }
4521    }
4522
4523    @Override
4524    public boolean willActivityBeVisible(IBinder token) {
4525        synchronized(this) {
4526            ActivityStack stack = ActivityRecord.getStackLocked(token);
4527            if (stack != null) {
4528                return stack.willActivityBeVisibleLocked(token);
4529            }
4530            return false;
4531        }
4532    }
4533
4534    @Override
4535    public void overridePendingTransition(IBinder token, String packageName,
4536            int enterAnim, int exitAnim) {
4537        synchronized(this) {
4538            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4539            if (self == null) {
4540                return;
4541            }
4542
4543            final long origId = Binder.clearCallingIdentity();
4544
4545            if (self.state == ActivityState.RESUMED
4546                    || self.state == ActivityState.PAUSING) {
4547                mWindowManager.overridePendingAppTransition(packageName,
4548                        enterAnim, exitAnim, null);
4549            }
4550
4551            Binder.restoreCallingIdentity(origId);
4552        }
4553    }
4554
4555    /**
4556     * Main function for removing an existing process from the activity manager
4557     * as a result of that process going away.  Clears out all connections
4558     * to the process.
4559     */
4560    private final void handleAppDiedLocked(ProcessRecord app,
4561            boolean restarting, boolean allowRestart) {
4562        int pid = app.pid;
4563        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4564        if (!kept && !restarting) {
4565            removeLruProcessLocked(app);
4566            if (pid > 0) {
4567                ProcessList.remove(pid);
4568            }
4569        }
4570
4571        if (mProfileProc == app) {
4572            clearProfilerLocked();
4573        }
4574
4575        // Remove this application's activities from active lists.
4576        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4577
4578        app.activities.clear();
4579
4580        if (app.instrumentationClass != null) {
4581            Slog.w(TAG, "Crash of app " + app.processName
4582                  + " running instrumentation " + app.instrumentationClass);
4583            Bundle info = new Bundle();
4584            info.putString("shortMsg", "Process crashed.");
4585            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4586        }
4587
4588        if (!restarting) {
4589            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4590                // If there was nothing to resume, and we are not already
4591                // restarting this process, but there is a visible activity that
4592                // is hosted by the process...  then make sure all visible
4593                // activities are running, taking care of restarting this
4594                // process.
4595                if (hasVisibleActivities) {
4596                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4597                }
4598            }
4599        }
4600    }
4601
4602    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4603        IBinder threadBinder = thread.asBinder();
4604        // Find the application record.
4605        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4606            ProcessRecord rec = mLruProcesses.get(i);
4607            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4608                return i;
4609            }
4610        }
4611        return -1;
4612    }
4613
4614    final ProcessRecord getRecordForAppLocked(
4615            IApplicationThread thread) {
4616        if (thread == null) {
4617            return null;
4618        }
4619
4620        int appIndex = getLRURecordIndexForAppLocked(thread);
4621        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4622    }
4623
4624    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4625        // If there are no longer any background processes running,
4626        // and the app that died was not running instrumentation,
4627        // then tell everyone we are now low on memory.
4628        boolean haveBg = false;
4629        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4630            ProcessRecord rec = mLruProcesses.get(i);
4631            if (rec.thread != null
4632                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4633                haveBg = true;
4634                break;
4635            }
4636        }
4637
4638        if (!haveBg) {
4639            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4640            if (doReport) {
4641                long now = SystemClock.uptimeMillis();
4642                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4643                    doReport = false;
4644                } else {
4645                    mLastMemUsageReportTime = now;
4646                }
4647            }
4648            final ArrayList<ProcessMemInfo> memInfos
4649                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4650            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4651            long now = SystemClock.uptimeMillis();
4652            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4653                ProcessRecord rec = mLruProcesses.get(i);
4654                if (rec == dyingProc || rec.thread == null) {
4655                    continue;
4656                }
4657                if (doReport) {
4658                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4659                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4660                }
4661                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4662                    // The low memory report is overriding any current
4663                    // state for a GC request.  Make sure to do
4664                    // heavy/important/visible/foreground processes first.
4665                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4666                        rec.lastRequestedGc = 0;
4667                    } else {
4668                        rec.lastRequestedGc = rec.lastLowMemory;
4669                    }
4670                    rec.reportLowMemory = true;
4671                    rec.lastLowMemory = now;
4672                    mProcessesToGc.remove(rec);
4673                    addProcessToGcListLocked(rec);
4674                }
4675            }
4676            if (doReport) {
4677                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4678                mHandler.sendMessage(msg);
4679            }
4680            scheduleAppGcsLocked();
4681        }
4682    }
4683
4684    final void appDiedLocked(ProcessRecord app) {
4685       appDiedLocked(app, app.pid, app.thread);
4686    }
4687
4688    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4689        // First check if this ProcessRecord is actually active for the pid.
4690        synchronized (mPidsSelfLocked) {
4691            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4692            if (curProc != app) {
4693                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4694                return;
4695            }
4696        }
4697
4698        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4699        synchronized (stats) {
4700            stats.noteProcessDiedLocked(app.info.uid, pid);
4701        }
4702
4703        Process.killProcessQuiet(pid);
4704        Process.killProcessGroup(app.info.uid, pid);
4705        app.killed = true;
4706
4707        // Clean up already done if the process has been re-started.
4708        if (app.pid == pid && app.thread != null &&
4709                app.thread.asBinder() == thread.asBinder()) {
4710            boolean doLowMem = app.instrumentationClass == null;
4711            boolean doOomAdj = doLowMem;
4712            if (!app.killedByAm) {
4713                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4714                        + ") has died");
4715                mAllowLowerMemLevel = true;
4716            } else {
4717                // Note that we always want to do oom adj to update our state with the
4718                // new number of procs.
4719                mAllowLowerMemLevel = false;
4720                doLowMem = false;
4721            }
4722            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4723            if (DEBUG_CLEANUP) Slog.v(
4724                TAG, "Dying app: " + app + ", pid: " + pid
4725                + ", thread: " + thread.asBinder());
4726            handleAppDiedLocked(app, false, true);
4727
4728            if (doOomAdj) {
4729                updateOomAdjLocked();
4730            }
4731            if (doLowMem) {
4732                doLowMemReportIfNeededLocked(app);
4733            }
4734        } else if (app.pid != pid) {
4735            // A new process has already been started.
4736            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4737                    + ") has died and restarted (pid " + app.pid + ").");
4738            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4739        } else if (DEBUG_PROCESSES) {
4740            Slog.d(TAG, "Received spurious death notification for thread "
4741                    + thread.asBinder());
4742        }
4743    }
4744
4745    /**
4746     * If a stack trace dump file is configured, dump process stack traces.
4747     * @param clearTraces causes the dump file to be erased prior to the new
4748     *    traces being written, if true; when false, the new traces will be
4749     *    appended to any existing file content.
4750     * @param firstPids of dalvik VM processes to dump stack traces for first
4751     * @param lastPids of dalvik VM processes to dump stack traces for last
4752     * @param nativeProcs optional list of native process names to dump stack crawls
4753     * @return file containing stack traces, or null if no dump file is configured
4754     */
4755    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4756            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4757        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4758        if (tracesPath == null || tracesPath.length() == 0) {
4759            return null;
4760        }
4761
4762        File tracesFile = new File(tracesPath);
4763        try {
4764            File tracesDir = tracesFile.getParentFile();
4765            if (!tracesDir.exists()) {
4766                tracesDir.mkdirs();
4767                if (!SELinux.restorecon(tracesDir)) {
4768                    return null;
4769                }
4770            }
4771            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4772
4773            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4774            tracesFile.createNewFile();
4775            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4776        } catch (IOException e) {
4777            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4778            return null;
4779        }
4780
4781        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4782        return tracesFile;
4783    }
4784
4785    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4786            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4787        // Use a FileObserver to detect when traces finish writing.
4788        // The order of traces is considered important to maintain for legibility.
4789        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4790            @Override
4791            public synchronized void onEvent(int event, String path) { notify(); }
4792        };
4793
4794        try {
4795            observer.startWatching();
4796
4797            // First collect all of the stacks of the most important pids.
4798            if (firstPids != null) {
4799                try {
4800                    int num = firstPids.size();
4801                    for (int i = 0; i < num; i++) {
4802                        synchronized (observer) {
4803                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4804                            observer.wait(200);  // Wait for write-close, give up after 200msec
4805                        }
4806                    }
4807                } catch (InterruptedException e) {
4808                    Slog.wtf(TAG, e);
4809                }
4810            }
4811
4812            // Next collect the stacks of the native pids
4813            if (nativeProcs != null) {
4814                int[] pids = Process.getPidsForCommands(nativeProcs);
4815                if (pids != null) {
4816                    for (int pid : pids) {
4817                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4818                    }
4819                }
4820            }
4821
4822            // Lastly, measure CPU usage.
4823            if (processCpuTracker != null) {
4824                processCpuTracker.init();
4825                System.gc();
4826                processCpuTracker.update();
4827                try {
4828                    synchronized (processCpuTracker) {
4829                        processCpuTracker.wait(500); // measure over 1/2 second.
4830                    }
4831                } catch (InterruptedException e) {
4832                }
4833                processCpuTracker.update();
4834
4835                // We'll take the stack crawls of just the top apps using CPU.
4836                final int N = processCpuTracker.countWorkingStats();
4837                int numProcs = 0;
4838                for (int i=0; i<N && numProcs<5; i++) {
4839                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4840                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4841                        numProcs++;
4842                        try {
4843                            synchronized (observer) {
4844                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4845                                observer.wait(200);  // Wait for write-close, give up after 200msec
4846                            }
4847                        } catch (InterruptedException e) {
4848                            Slog.wtf(TAG, e);
4849                        }
4850
4851                    }
4852                }
4853            }
4854        } finally {
4855            observer.stopWatching();
4856        }
4857    }
4858
4859    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4860        if (true || IS_USER_BUILD) {
4861            return;
4862        }
4863        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4864        if (tracesPath == null || tracesPath.length() == 0) {
4865            return;
4866        }
4867
4868        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4869        StrictMode.allowThreadDiskWrites();
4870        try {
4871            final File tracesFile = new File(tracesPath);
4872            final File tracesDir = tracesFile.getParentFile();
4873            final File tracesTmp = new File(tracesDir, "__tmp__");
4874            try {
4875                if (!tracesDir.exists()) {
4876                    tracesDir.mkdirs();
4877                    if (!SELinux.restorecon(tracesDir.getPath())) {
4878                        return;
4879                    }
4880                }
4881                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4882
4883                if (tracesFile.exists()) {
4884                    tracesTmp.delete();
4885                    tracesFile.renameTo(tracesTmp);
4886                }
4887                StringBuilder sb = new StringBuilder();
4888                Time tobj = new Time();
4889                tobj.set(System.currentTimeMillis());
4890                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4891                sb.append(": ");
4892                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4893                sb.append(" since ");
4894                sb.append(msg);
4895                FileOutputStream fos = new FileOutputStream(tracesFile);
4896                fos.write(sb.toString().getBytes());
4897                if (app == null) {
4898                    fos.write("\n*** No application process!".getBytes());
4899                }
4900                fos.close();
4901                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4902            } catch (IOException e) {
4903                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4904                return;
4905            }
4906
4907            if (app != null) {
4908                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4909                firstPids.add(app.pid);
4910                dumpStackTraces(tracesPath, firstPids, null, null, null);
4911            }
4912
4913            File lastTracesFile = null;
4914            File curTracesFile = null;
4915            for (int i=9; i>=0; i--) {
4916                String name = String.format(Locale.US, "slow%02d.txt", i);
4917                curTracesFile = new File(tracesDir, name);
4918                if (curTracesFile.exists()) {
4919                    if (lastTracesFile != null) {
4920                        curTracesFile.renameTo(lastTracesFile);
4921                    } else {
4922                        curTracesFile.delete();
4923                    }
4924                }
4925                lastTracesFile = curTracesFile;
4926            }
4927            tracesFile.renameTo(curTracesFile);
4928            if (tracesTmp.exists()) {
4929                tracesTmp.renameTo(tracesFile);
4930            }
4931        } finally {
4932            StrictMode.setThreadPolicy(oldPolicy);
4933        }
4934    }
4935
4936    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4937            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4938        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4939        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4940
4941        if (mController != null) {
4942            try {
4943                // 0 == continue, -1 = kill process immediately
4944                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4945                if (res < 0 && app.pid != MY_PID) {
4946                    app.kill("anr", true);
4947                }
4948            } catch (RemoteException e) {
4949                mController = null;
4950                Watchdog.getInstance().setActivityController(null);
4951            }
4952        }
4953
4954        long anrTime = SystemClock.uptimeMillis();
4955        if (MONITOR_CPU_USAGE) {
4956            updateCpuStatsNow();
4957        }
4958
4959        synchronized (this) {
4960            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4961            if (mShuttingDown) {
4962                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4963                return;
4964            } else if (app.notResponding) {
4965                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4966                return;
4967            } else if (app.crashing) {
4968                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4969                return;
4970            }
4971
4972            // In case we come through here for the same app before completing
4973            // this one, mark as anring now so we will bail out.
4974            app.notResponding = true;
4975
4976            // Log the ANR to the event log.
4977            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4978                    app.processName, app.info.flags, annotation);
4979
4980            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4981            firstPids.add(app.pid);
4982
4983            int parentPid = app.pid;
4984            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4985            if (parentPid != app.pid) firstPids.add(parentPid);
4986
4987            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4988
4989            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4990                ProcessRecord r = mLruProcesses.get(i);
4991                if (r != null && r.thread != null) {
4992                    int pid = r.pid;
4993                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4994                        if (r.persistent) {
4995                            firstPids.add(pid);
4996                        } else {
4997                            lastPids.put(pid, Boolean.TRUE);
4998                        }
4999                    }
5000                }
5001            }
5002        }
5003
5004        // Log the ANR to the main log.
5005        StringBuilder info = new StringBuilder();
5006        info.setLength(0);
5007        info.append("ANR in ").append(app.processName);
5008        if (activity != null && activity.shortComponentName != null) {
5009            info.append(" (").append(activity.shortComponentName).append(")");
5010        }
5011        info.append("\n");
5012        info.append("PID: ").append(app.pid).append("\n");
5013        if (annotation != null) {
5014            info.append("Reason: ").append(annotation).append("\n");
5015        }
5016        if (parent != null && parent != activity) {
5017            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5018        }
5019
5020        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5021
5022        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5023                NATIVE_STACKS_OF_INTEREST);
5024
5025        String cpuInfo = null;
5026        if (MONITOR_CPU_USAGE) {
5027            updateCpuStatsNow();
5028            synchronized (mProcessCpuTracker) {
5029                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5030            }
5031            info.append(processCpuTracker.printCurrentLoad());
5032            info.append(cpuInfo);
5033        }
5034
5035        info.append(processCpuTracker.printCurrentState(anrTime));
5036
5037        Slog.e(TAG, info.toString());
5038        if (tracesFile == null) {
5039            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5040            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5041        }
5042
5043        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5044                cpuInfo, tracesFile, null);
5045
5046        if (mController != null) {
5047            try {
5048                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5049                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5050                if (res != 0) {
5051                    if (res < 0 && app.pid != MY_PID) {
5052                        app.kill("anr", true);
5053                    } else {
5054                        synchronized (this) {
5055                            mServices.scheduleServiceTimeoutLocked(app);
5056                        }
5057                    }
5058                    return;
5059                }
5060            } catch (RemoteException e) {
5061                mController = null;
5062                Watchdog.getInstance().setActivityController(null);
5063            }
5064        }
5065
5066        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5067        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5068                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5069
5070        synchronized (this) {
5071            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5072                app.kill("bg anr", true);
5073                return;
5074            }
5075
5076            // Set the app's notResponding state, and look up the errorReportReceiver
5077            makeAppNotRespondingLocked(app,
5078                    activity != null ? activity.shortComponentName : null,
5079                    annotation != null ? "ANR " + annotation : "ANR",
5080                    info.toString());
5081
5082            // Bring up the infamous App Not Responding dialog
5083            Message msg = Message.obtain();
5084            HashMap<String, Object> map = new HashMap<String, Object>();
5085            msg.what = SHOW_NOT_RESPONDING_MSG;
5086            msg.obj = map;
5087            msg.arg1 = aboveSystem ? 1 : 0;
5088            map.put("app", app);
5089            if (activity != null) {
5090                map.put("activity", activity);
5091            }
5092
5093            mHandler.sendMessage(msg);
5094        }
5095    }
5096
5097    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5098        if (!mLaunchWarningShown) {
5099            mLaunchWarningShown = true;
5100            mHandler.post(new Runnable() {
5101                @Override
5102                public void run() {
5103                    synchronized (ActivityManagerService.this) {
5104                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5105                        d.show();
5106                        mHandler.postDelayed(new Runnable() {
5107                            @Override
5108                            public void run() {
5109                                synchronized (ActivityManagerService.this) {
5110                                    d.dismiss();
5111                                    mLaunchWarningShown = false;
5112                                }
5113                            }
5114                        }, 4000);
5115                    }
5116                }
5117            });
5118        }
5119    }
5120
5121    @Override
5122    public boolean clearApplicationUserData(final String packageName,
5123            final IPackageDataObserver observer, int userId) {
5124        enforceNotIsolatedCaller("clearApplicationUserData");
5125        int uid = Binder.getCallingUid();
5126        int pid = Binder.getCallingPid();
5127        userId = handleIncomingUser(pid, uid,
5128                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5129        long callingId = Binder.clearCallingIdentity();
5130        try {
5131            IPackageManager pm = AppGlobals.getPackageManager();
5132            int pkgUid = -1;
5133            synchronized(this) {
5134                try {
5135                    pkgUid = pm.getPackageUid(packageName, userId);
5136                } catch (RemoteException e) {
5137                }
5138                if (pkgUid == -1) {
5139                    Slog.w(TAG, "Invalid packageName: " + packageName);
5140                    if (observer != null) {
5141                        try {
5142                            observer.onRemoveCompleted(packageName, false);
5143                        } catch (RemoteException e) {
5144                            Slog.i(TAG, "Observer no longer exists.");
5145                        }
5146                    }
5147                    return false;
5148                }
5149                if (uid == pkgUid || checkComponentPermission(
5150                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5151                        pid, uid, -1, true)
5152                        == PackageManager.PERMISSION_GRANTED) {
5153                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5154                } else {
5155                    throw new SecurityException("PID " + pid + " does not have permission "
5156                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5157                                    + " of package " + packageName);
5158                }
5159
5160                // Remove all tasks match the cleared application package and user
5161                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5162                    final TaskRecord tr = mRecentTasks.get(i);
5163                    final String taskPackageName =
5164                            tr.getBaseIntent().getComponent().getPackageName();
5165                    if (tr.userId != userId) continue;
5166                    if (!taskPackageName.equals(packageName)) continue;
5167                    removeTaskByIdLocked(tr.taskId, false);
5168                }
5169            }
5170
5171            try {
5172                // Clear application user data
5173                pm.clearApplicationUserData(packageName, observer, userId);
5174
5175                synchronized(this) {
5176                    // Remove all permissions granted from/to this package
5177                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5178                }
5179
5180                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5181                        Uri.fromParts("package", packageName, null));
5182                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5183                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5184                        null, null, 0, null, null, null, false, false, userId);
5185            } catch (RemoteException e) {
5186            }
5187        } finally {
5188            Binder.restoreCallingIdentity(callingId);
5189        }
5190        return true;
5191    }
5192
5193    @Override
5194    public void killBackgroundProcesses(final String packageName, int userId) {
5195        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5196                != PackageManager.PERMISSION_GRANTED &&
5197                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5198                        != PackageManager.PERMISSION_GRANTED) {
5199            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5200                    + Binder.getCallingPid()
5201                    + ", uid=" + Binder.getCallingUid()
5202                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5203            Slog.w(TAG, msg);
5204            throw new SecurityException(msg);
5205        }
5206
5207        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5208                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5209        long callingId = Binder.clearCallingIdentity();
5210        try {
5211            IPackageManager pm = AppGlobals.getPackageManager();
5212            synchronized(this) {
5213                int appId = -1;
5214                try {
5215                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5216                } catch (RemoteException e) {
5217                }
5218                if (appId == -1) {
5219                    Slog.w(TAG, "Invalid packageName: " + packageName);
5220                    return;
5221                }
5222                killPackageProcessesLocked(packageName, appId, userId,
5223                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5224            }
5225        } finally {
5226            Binder.restoreCallingIdentity(callingId);
5227        }
5228    }
5229
5230    @Override
5231    public void killAllBackgroundProcesses() {
5232        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5233                != PackageManager.PERMISSION_GRANTED) {
5234            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5235                    + Binder.getCallingPid()
5236                    + ", uid=" + Binder.getCallingUid()
5237                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5238            Slog.w(TAG, msg);
5239            throw new SecurityException(msg);
5240        }
5241
5242        long callingId = Binder.clearCallingIdentity();
5243        try {
5244            synchronized(this) {
5245                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5246                final int NP = mProcessNames.getMap().size();
5247                for (int ip=0; ip<NP; ip++) {
5248                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5249                    final int NA = apps.size();
5250                    for (int ia=0; ia<NA; ia++) {
5251                        ProcessRecord app = apps.valueAt(ia);
5252                        if (app.persistent) {
5253                            // we don't kill persistent processes
5254                            continue;
5255                        }
5256                        if (app.removed) {
5257                            procs.add(app);
5258                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5259                            app.removed = true;
5260                            procs.add(app);
5261                        }
5262                    }
5263                }
5264
5265                int N = procs.size();
5266                for (int i=0; i<N; i++) {
5267                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5268                }
5269                mAllowLowerMemLevel = true;
5270                updateOomAdjLocked();
5271                doLowMemReportIfNeededLocked(null);
5272            }
5273        } finally {
5274            Binder.restoreCallingIdentity(callingId);
5275        }
5276    }
5277
5278    @Override
5279    public void forceStopPackage(final String packageName, int userId) {
5280        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5281                != PackageManager.PERMISSION_GRANTED) {
5282            String msg = "Permission Denial: forceStopPackage() from pid="
5283                    + Binder.getCallingPid()
5284                    + ", uid=" + Binder.getCallingUid()
5285                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5286            Slog.w(TAG, msg);
5287            throw new SecurityException(msg);
5288        }
5289        final int callingPid = Binder.getCallingPid();
5290        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5291                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5292        long callingId = Binder.clearCallingIdentity();
5293        try {
5294            IPackageManager pm = AppGlobals.getPackageManager();
5295            synchronized(this) {
5296                int[] users = userId == UserHandle.USER_ALL
5297                        ? getUsersLocked() : new int[] { userId };
5298                for (int user : users) {
5299                    int pkgUid = -1;
5300                    try {
5301                        pkgUid = pm.getPackageUid(packageName, user);
5302                    } catch (RemoteException e) {
5303                    }
5304                    if (pkgUid == -1) {
5305                        Slog.w(TAG, "Invalid packageName: " + packageName);
5306                        continue;
5307                    }
5308                    try {
5309                        pm.setPackageStoppedState(packageName, true, user);
5310                    } catch (RemoteException e) {
5311                    } catch (IllegalArgumentException e) {
5312                        Slog.w(TAG, "Failed trying to unstop package "
5313                                + packageName + ": " + e);
5314                    }
5315                    if (isUserRunningLocked(user, false)) {
5316                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5317                    }
5318                }
5319            }
5320        } finally {
5321            Binder.restoreCallingIdentity(callingId);
5322        }
5323    }
5324
5325    @Override
5326    public void addPackageDependency(String packageName) {
5327        synchronized (this) {
5328            int callingPid = Binder.getCallingPid();
5329            if (callingPid == Process.myPid()) {
5330                //  Yeah, um, no.
5331                Slog.w(TAG, "Can't addPackageDependency on system process");
5332                return;
5333            }
5334            ProcessRecord proc;
5335            synchronized (mPidsSelfLocked) {
5336                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5337            }
5338            if (proc != null) {
5339                if (proc.pkgDeps == null) {
5340                    proc.pkgDeps = new ArraySet<String>(1);
5341                }
5342                proc.pkgDeps.add(packageName);
5343            }
5344        }
5345    }
5346
5347    /*
5348     * The pkg name and app id have to be specified.
5349     */
5350    @Override
5351    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5352        if (pkg == null) {
5353            return;
5354        }
5355        // Make sure the uid is valid.
5356        if (appid < 0) {
5357            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5358            return;
5359        }
5360        int callerUid = Binder.getCallingUid();
5361        // Only the system server can kill an application
5362        if (callerUid == Process.SYSTEM_UID) {
5363            // Post an aysnc message to kill the application
5364            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5365            msg.arg1 = appid;
5366            msg.arg2 = 0;
5367            Bundle bundle = new Bundle();
5368            bundle.putString("pkg", pkg);
5369            bundle.putString("reason", reason);
5370            msg.obj = bundle;
5371            mHandler.sendMessage(msg);
5372        } else {
5373            throw new SecurityException(callerUid + " cannot kill pkg: " +
5374                    pkg);
5375        }
5376    }
5377
5378    @Override
5379    public void closeSystemDialogs(String reason) {
5380        enforceNotIsolatedCaller("closeSystemDialogs");
5381
5382        final int pid = Binder.getCallingPid();
5383        final int uid = Binder.getCallingUid();
5384        final long origId = Binder.clearCallingIdentity();
5385        try {
5386            synchronized (this) {
5387                // Only allow this from foreground processes, so that background
5388                // applications can't abuse it to prevent system UI from being shown.
5389                if (uid >= Process.FIRST_APPLICATION_UID) {
5390                    ProcessRecord proc;
5391                    synchronized (mPidsSelfLocked) {
5392                        proc = mPidsSelfLocked.get(pid);
5393                    }
5394                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5395                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5396                                + " from background process " + proc);
5397                        return;
5398                    }
5399                }
5400                closeSystemDialogsLocked(reason);
5401            }
5402        } finally {
5403            Binder.restoreCallingIdentity(origId);
5404        }
5405    }
5406
5407    void closeSystemDialogsLocked(String reason) {
5408        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5409        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5410                | Intent.FLAG_RECEIVER_FOREGROUND);
5411        if (reason != null) {
5412            intent.putExtra("reason", reason);
5413        }
5414        mWindowManager.closeSystemDialogs(reason);
5415
5416        mStackSupervisor.closeSystemDialogsLocked();
5417
5418        broadcastIntentLocked(null, null, intent, null,
5419                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5420                Process.SYSTEM_UID, UserHandle.USER_ALL);
5421    }
5422
5423    @Override
5424    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5425        enforceNotIsolatedCaller("getProcessMemoryInfo");
5426        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5427        for (int i=pids.length-1; i>=0; i--) {
5428            ProcessRecord proc;
5429            int oomAdj;
5430            synchronized (this) {
5431                synchronized (mPidsSelfLocked) {
5432                    proc = mPidsSelfLocked.get(pids[i]);
5433                    oomAdj = proc != null ? proc.setAdj : 0;
5434                }
5435            }
5436            infos[i] = new Debug.MemoryInfo();
5437            Debug.getMemoryInfo(pids[i], infos[i]);
5438            if (proc != null) {
5439                synchronized (this) {
5440                    if (proc.thread != null && proc.setAdj == oomAdj) {
5441                        // Record this for posterity if the process has been stable.
5442                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5443                                infos[i].getTotalUss(), false, proc.pkgList);
5444                    }
5445                }
5446            }
5447        }
5448        return infos;
5449    }
5450
5451    @Override
5452    public long[] getProcessPss(int[] pids) {
5453        enforceNotIsolatedCaller("getProcessPss");
5454        long[] pss = new long[pids.length];
5455        for (int i=pids.length-1; i>=0; i--) {
5456            ProcessRecord proc;
5457            int oomAdj;
5458            synchronized (this) {
5459                synchronized (mPidsSelfLocked) {
5460                    proc = mPidsSelfLocked.get(pids[i]);
5461                    oomAdj = proc != null ? proc.setAdj : 0;
5462                }
5463            }
5464            long[] tmpUss = new long[1];
5465            pss[i] = Debug.getPss(pids[i], tmpUss);
5466            if (proc != null) {
5467                synchronized (this) {
5468                    if (proc.thread != null && proc.setAdj == oomAdj) {
5469                        // Record this for posterity if the process has been stable.
5470                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5471                    }
5472                }
5473            }
5474        }
5475        return pss;
5476    }
5477
5478    @Override
5479    public void killApplicationProcess(String processName, int uid) {
5480        if (processName == null) {
5481            return;
5482        }
5483
5484        int callerUid = Binder.getCallingUid();
5485        // Only the system server can kill an application
5486        if (callerUid == Process.SYSTEM_UID) {
5487            synchronized (this) {
5488                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5489                if (app != null && app.thread != null) {
5490                    try {
5491                        app.thread.scheduleSuicide();
5492                    } catch (RemoteException e) {
5493                        // If the other end already died, then our work here is done.
5494                    }
5495                } else {
5496                    Slog.w(TAG, "Process/uid not found attempting kill of "
5497                            + processName + " / " + uid);
5498                }
5499            }
5500        } else {
5501            throw new SecurityException(callerUid + " cannot kill app process: " +
5502                    processName);
5503        }
5504    }
5505
5506    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5507        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5508                false, true, false, false, UserHandle.getUserId(uid), reason);
5509        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5510                Uri.fromParts("package", packageName, null));
5511        if (!mProcessesReady) {
5512            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5513                    | Intent.FLAG_RECEIVER_FOREGROUND);
5514        }
5515        intent.putExtra(Intent.EXTRA_UID, uid);
5516        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5517        broadcastIntentLocked(null, null, intent,
5518                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5519                false, false,
5520                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5521    }
5522
5523    private void forceStopUserLocked(int userId, String reason) {
5524        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5525        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5526        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5527                | Intent.FLAG_RECEIVER_FOREGROUND);
5528        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5529        broadcastIntentLocked(null, null, intent,
5530                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5531                false, false,
5532                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5533    }
5534
5535    private final boolean killPackageProcessesLocked(String packageName, int appId,
5536            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5537            boolean doit, boolean evenPersistent, String reason) {
5538        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5539
5540        // Remove all processes this package may have touched: all with the
5541        // same UID (except for the system or root user), and all whose name
5542        // matches the package name.
5543        final int NP = mProcessNames.getMap().size();
5544        for (int ip=0; ip<NP; ip++) {
5545            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5546            final int NA = apps.size();
5547            for (int ia=0; ia<NA; ia++) {
5548                ProcessRecord app = apps.valueAt(ia);
5549                if (app.persistent && !evenPersistent) {
5550                    // we don't kill persistent processes
5551                    continue;
5552                }
5553                if (app.removed) {
5554                    if (doit) {
5555                        procs.add(app);
5556                    }
5557                    continue;
5558                }
5559
5560                // Skip process if it doesn't meet our oom adj requirement.
5561                if (app.setAdj < minOomAdj) {
5562                    continue;
5563                }
5564
5565                // If no package is specified, we call all processes under the
5566                // give user id.
5567                if (packageName == null) {
5568                    if (app.userId != userId) {
5569                        continue;
5570                    }
5571                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5572                        continue;
5573                    }
5574                // Package has been specified, we want to hit all processes
5575                // that match it.  We need to qualify this by the processes
5576                // that are running under the specified app and user ID.
5577                } else {
5578                    final boolean isDep = app.pkgDeps != null
5579                            && app.pkgDeps.contains(packageName);
5580                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5581                        continue;
5582                    }
5583                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5584                        continue;
5585                    }
5586                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5587                        continue;
5588                    }
5589                }
5590
5591                // Process has passed all conditions, kill it!
5592                if (!doit) {
5593                    return true;
5594                }
5595                app.removed = true;
5596                procs.add(app);
5597            }
5598        }
5599
5600        int N = procs.size();
5601        for (int i=0; i<N; i++) {
5602            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5603        }
5604        updateOomAdjLocked();
5605        return N > 0;
5606    }
5607
5608    private final boolean forceStopPackageLocked(String name, int appId,
5609            boolean callerWillRestart, boolean purgeCache, boolean doit,
5610            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5611        int i;
5612        int N;
5613
5614        if (userId == UserHandle.USER_ALL && name == null) {
5615            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5616        }
5617
5618        if (appId < 0 && name != null) {
5619            try {
5620                appId = UserHandle.getAppId(
5621                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5622            } catch (RemoteException e) {
5623            }
5624        }
5625
5626        if (doit) {
5627            if (name != null) {
5628                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5629                        + " user=" + userId + ": " + reason);
5630            } else {
5631                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5632            }
5633
5634            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5635            for (int ip=pmap.size()-1; ip>=0; ip--) {
5636                SparseArray<Long> ba = pmap.valueAt(ip);
5637                for (i=ba.size()-1; i>=0; i--) {
5638                    boolean remove = false;
5639                    final int entUid = ba.keyAt(i);
5640                    if (name != null) {
5641                        if (userId == UserHandle.USER_ALL) {
5642                            if (UserHandle.getAppId(entUid) == appId) {
5643                                remove = true;
5644                            }
5645                        } else {
5646                            if (entUid == UserHandle.getUid(userId, appId)) {
5647                                remove = true;
5648                            }
5649                        }
5650                    } else if (UserHandle.getUserId(entUid) == userId) {
5651                        remove = true;
5652                    }
5653                    if (remove) {
5654                        ba.removeAt(i);
5655                    }
5656                }
5657                if (ba.size() == 0) {
5658                    pmap.removeAt(ip);
5659                }
5660            }
5661        }
5662
5663        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5664                -100, callerWillRestart, true, doit, evenPersistent,
5665                name == null ? ("stop user " + userId) : ("stop " + name));
5666
5667        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5668            if (!doit) {
5669                return true;
5670            }
5671            didSomething = true;
5672        }
5673
5674        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5675            if (!doit) {
5676                return true;
5677            }
5678            didSomething = true;
5679        }
5680
5681        if (name == null) {
5682            // Remove all sticky broadcasts from this user.
5683            mStickyBroadcasts.remove(userId);
5684        }
5685
5686        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5687        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5688                userId, providers)) {
5689            if (!doit) {
5690                return true;
5691            }
5692            didSomething = true;
5693        }
5694        N = providers.size();
5695        for (i=0; i<N; i++) {
5696            removeDyingProviderLocked(null, providers.get(i), true);
5697        }
5698
5699        // Remove transient permissions granted from/to this package/user
5700        removeUriPermissionsForPackageLocked(name, userId, false);
5701
5702        if (name == null || uninstalling) {
5703            // Remove pending intents.  For now we only do this when force
5704            // stopping users, because we have some problems when doing this
5705            // for packages -- app widgets are not currently cleaned up for
5706            // such packages, so they can be left with bad pending intents.
5707            if (mIntentSenderRecords.size() > 0) {
5708                Iterator<WeakReference<PendingIntentRecord>> it
5709                        = mIntentSenderRecords.values().iterator();
5710                while (it.hasNext()) {
5711                    WeakReference<PendingIntentRecord> wpir = it.next();
5712                    if (wpir == null) {
5713                        it.remove();
5714                        continue;
5715                    }
5716                    PendingIntentRecord pir = wpir.get();
5717                    if (pir == null) {
5718                        it.remove();
5719                        continue;
5720                    }
5721                    if (name == null) {
5722                        // Stopping user, remove all objects for the user.
5723                        if (pir.key.userId != userId) {
5724                            // Not the same user, skip it.
5725                            continue;
5726                        }
5727                    } else {
5728                        if (UserHandle.getAppId(pir.uid) != appId) {
5729                            // Different app id, skip it.
5730                            continue;
5731                        }
5732                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5733                            // Different user, skip it.
5734                            continue;
5735                        }
5736                        if (!pir.key.packageName.equals(name)) {
5737                            // Different package, skip it.
5738                            continue;
5739                        }
5740                    }
5741                    if (!doit) {
5742                        return true;
5743                    }
5744                    didSomething = true;
5745                    it.remove();
5746                    pir.canceled = true;
5747                    if (pir.key.activity != null) {
5748                        pir.key.activity.pendingResults.remove(pir.ref);
5749                    }
5750                }
5751            }
5752        }
5753
5754        if (doit) {
5755            if (purgeCache && name != null) {
5756                AttributeCache ac = AttributeCache.instance();
5757                if (ac != null) {
5758                    ac.removePackage(name);
5759                }
5760            }
5761            if (mBooted) {
5762                mStackSupervisor.resumeTopActivitiesLocked();
5763                mStackSupervisor.scheduleIdleLocked();
5764            }
5765        }
5766
5767        return didSomething;
5768    }
5769
5770    private final boolean removeProcessLocked(ProcessRecord app,
5771            boolean callerWillRestart, boolean allowRestart, String reason) {
5772        final String name = app.processName;
5773        final int uid = app.uid;
5774        if (DEBUG_PROCESSES) Slog.d(
5775            TAG, "Force removing proc " + app.toShortString() + " (" + name
5776            + "/" + uid + ")");
5777
5778        mProcessNames.remove(name, uid);
5779        mIsolatedProcesses.remove(app.uid);
5780        if (mHeavyWeightProcess == app) {
5781            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5782                    mHeavyWeightProcess.userId, 0));
5783            mHeavyWeightProcess = null;
5784        }
5785        boolean needRestart = false;
5786        if (app.pid > 0 && app.pid != MY_PID) {
5787            int pid = app.pid;
5788            synchronized (mPidsSelfLocked) {
5789                mPidsSelfLocked.remove(pid);
5790                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5791            }
5792            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5793            if (app.isolated) {
5794                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5795            }
5796            app.kill(reason, true);
5797            handleAppDiedLocked(app, true, allowRestart);
5798            removeLruProcessLocked(app);
5799
5800            if (app.persistent && !app.isolated) {
5801                if (!callerWillRestart) {
5802                    addAppLocked(app.info, false, null /* ABI override */);
5803                } else {
5804                    needRestart = true;
5805                }
5806            }
5807        } else {
5808            mRemovedProcesses.add(app);
5809        }
5810
5811        return needRestart;
5812    }
5813
5814    private final void processStartTimedOutLocked(ProcessRecord app) {
5815        final int pid = app.pid;
5816        boolean gone = false;
5817        synchronized (mPidsSelfLocked) {
5818            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5819            if (knownApp != null && knownApp.thread == null) {
5820                mPidsSelfLocked.remove(pid);
5821                gone = true;
5822            }
5823        }
5824
5825        if (gone) {
5826            Slog.w(TAG, "Process " + app + " failed to attach");
5827            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5828                    pid, app.uid, app.processName);
5829            mProcessNames.remove(app.processName, app.uid);
5830            mIsolatedProcesses.remove(app.uid);
5831            if (mHeavyWeightProcess == app) {
5832                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5833                        mHeavyWeightProcess.userId, 0));
5834                mHeavyWeightProcess = null;
5835            }
5836            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5837            if (app.isolated) {
5838                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5839            }
5840            // Take care of any launching providers waiting for this process.
5841            checkAppInLaunchingProvidersLocked(app, true);
5842            // Take care of any services that are waiting for the process.
5843            mServices.processStartTimedOutLocked(app);
5844            app.kill("start timeout", true);
5845            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5846                Slog.w(TAG, "Unattached app died before backup, skipping");
5847                try {
5848                    IBackupManager bm = IBackupManager.Stub.asInterface(
5849                            ServiceManager.getService(Context.BACKUP_SERVICE));
5850                    bm.agentDisconnected(app.info.packageName);
5851                } catch (RemoteException e) {
5852                    // Can't happen; the backup manager is local
5853                }
5854            }
5855            if (isPendingBroadcastProcessLocked(pid)) {
5856                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5857                skipPendingBroadcastLocked(pid);
5858            }
5859        } else {
5860            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5861        }
5862    }
5863
5864    private final boolean attachApplicationLocked(IApplicationThread thread,
5865            int pid) {
5866
5867        // Find the application record that is being attached...  either via
5868        // the pid if we are running in multiple processes, or just pull the
5869        // next app record if we are emulating process with anonymous threads.
5870        ProcessRecord app;
5871        if (pid != MY_PID && pid >= 0) {
5872            synchronized (mPidsSelfLocked) {
5873                app = mPidsSelfLocked.get(pid);
5874            }
5875        } else {
5876            app = null;
5877        }
5878
5879        if (app == null) {
5880            Slog.w(TAG, "No pending application record for pid " + pid
5881                    + " (IApplicationThread " + thread + "); dropping process");
5882            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5883            if (pid > 0 && pid != MY_PID) {
5884                Process.killProcessQuiet(pid);
5885                //TODO: Process.killProcessGroup(app.info.uid, pid);
5886            } else {
5887                try {
5888                    thread.scheduleExit();
5889                } catch (Exception e) {
5890                    // Ignore exceptions.
5891                }
5892            }
5893            return false;
5894        }
5895
5896        // If this application record is still attached to a previous
5897        // process, clean it up now.
5898        if (app.thread != null) {
5899            handleAppDiedLocked(app, true, true);
5900        }
5901
5902        // Tell the process all about itself.
5903
5904        if (localLOGV) Slog.v(
5905                TAG, "Binding process pid " + pid + " to record " + app);
5906
5907        final String processName = app.processName;
5908        try {
5909            AppDeathRecipient adr = new AppDeathRecipient(
5910                    app, pid, thread);
5911            thread.asBinder().linkToDeath(adr, 0);
5912            app.deathRecipient = adr;
5913        } catch (RemoteException e) {
5914            app.resetPackageList(mProcessStats);
5915            startProcessLocked(app, "link fail", processName);
5916            return false;
5917        }
5918
5919        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5920
5921        app.makeActive(thread, mProcessStats);
5922        app.curAdj = app.setAdj = -100;
5923        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5924        app.forcingToForeground = null;
5925        updateProcessForegroundLocked(app, false, false);
5926        app.hasShownUi = false;
5927        app.debugging = false;
5928        app.cached = false;
5929
5930        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5931
5932        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5933        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5934
5935        if (!normalMode) {
5936            Slog.i(TAG, "Launching preboot mode app: " + app);
5937        }
5938
5939        if (localLOGV) Slog.v(
5940            TAG, "New app record " + app
5941            + " thread=" + thread.asBinder() + " pid=" + pid);
5942        try {
5943            int testMode = IApplicationThread.DEBUG_OFF;
5944            if (mDebugApp != null && mDebugApp.equals(processName)) {
5945                testMode = mWaitForDebugger
5946                    ? IApplicationThread.DEBUG_WAIT
5947                    : IApplicationThread.DEBUG_ON;
5948                app.debugging = true;
5949                if (mDebugTransient) {
5950                    mDebugApp = mOrigDebugApp;
5951                    mWaitForDebugger = mOrigWaitForDebugger;
5952                }
5953            }
5954            String profileFile = app.instrumentationProfileFile;
5955            ParcelFileDescriptor profileFd = null;
5956            int samplingInterval = 0;
5957            boolean profileAutoStop = false;
5958            if (mProfileApp != null && mProfileApp.equals(processName)) {
5959                mProfileProc = app;
5960                profileFile = mProfileFile;
5961                profileFd = mProfileFd;
5962                samplingInterval = mSamplingInterval;
5963                profileAutoStop = mAutoStopProfiler;
5964            }
5965            boolean enableOpenGlTrace = false;
5966            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5967                enableOpenGlTrace = true;
5968                mOpenGlTraceApp = null;
5969            }
5970
5971            // If the app is being launched for restore or full backup, set it up specially
5972            boolean isRestrictedBackupMode = false;
5973            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5974                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5975                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5976                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5977            }
5978
5979            ensurePackageDexOpt(app.instrumentationInfo != null
5980                    ? app.instrumentationInfo.packageName
5981                    : app.info.packageName);
5982            if (app.instrumentationClass != null) {
5983                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5984            }
5985            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5986                    + processName + " with config " + mConfiguration);
5987            ApplicationInfo appInfo = app.instrumentationInfo != null
5988                    ? app.instrumentationInfo : app.info;
5989            app.compat = compatibilityInfoForPackageLocked(appInfo);
5990            if (profileFd != null) {
5991                profileFd = profileFd.dup();
5992            }
5993            ProfilerInfo profilerInfo = profileFile == null ? null
5994                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5995            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5996                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5997                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5998                    isRestrictedBackupMode || !normalMode, app.persistent,
5999                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6000                    mCoreSettingsObserver.getCoreSettingsLocked());
6001            updateLruProcessLocked(app, false, null);
6002            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6003        } catch (Exception e) {
6004            // todo: Yikes!  What should we do?  For now we will try to
6005            // start another process, but that could easily get us in
6006            // an infinite loop of restarting processes...
6007            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6008
6009            app.resetPackageList(mProcessStats);
6010            app.unlinkDeathRecipient();
6011            startProcessLocked(app, "bind fail", processName);
6012            return false;
6013        }
6014
6015        // Remove this record from the list of starting applications.
6016        mPersistentStartingProcesses.remove(app);
6017        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6018                "Attach application locked removing on hold: " + app);
6019        mProcessesOnHold.remove(app);
6020
6021        boolean badApp = false;
6022        boolean didSomething = false;
6023
6024        // See if the top visible activity is waiting to run in this process...
6025        if (normalMode) {
6026            try {
6027                if (mStackSupervisor.attachApplicationLocked(app)) {
6028                    didSomething = true;
6029                }
6030            } catch (Exception e) {
6031                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6032                badApp = true;
6033            }
6034        }
6035
6036        // Find any services that should be running in this process...
6037        if (!badApp) {
6038            try {
6039                didSomething |= mServices.attachApplicationLocked(app, processName);
6040            } catch (Exception e) {
6041                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6042                badApp = true;
6043            }
6044        }
6045
6046        // Check if a next-broadcast receiver is in this process...
6047        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6048            try {
6049                didSomething |= sendPendingBroadcastsLocked(app);
6050            } catch (Exception e) {
6051                // If the app died trying to launch the receiver we declare it 'bad'
6052                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6053                badApp = true;
6054            }
6055        }
6056
6057        // Check whether the next backup agent is in this process...
6058        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6059            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6060            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6061            try {
6062                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6063                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6064                        mBackupTarget.backupMode);
6065            } catch (Exception e) {
6066                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6067                badApp = true;
6068            }
6069        }
6070
6071        if (badApp) {
6072            app.kill("error during init", true);
6073            handleAppDiedLocked(app, false, true);
6074            return false;
6075        }
6076
6077        if (!didSomething) {
6078            updateOomAdjLocked();
6079        }
6080
6081        return true;
6082    }
6083
6084    @Override
6085    public final void attachApplication(IApplicationThread thread) {
6086        synchronized (this) {
6087            int callingPid = Binder.getCallingPid();
6088            final long origId = Binder.clearCallingIdentity();
6089            attachApplicationLocked(thread, callingPid);
6090            Binder.restoreCallingIdentity(origId);
6091        }
6092    }
6093
6094    @Override
6095    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6096        final long origId = Binder.clearCallingIdentity();
6097        synchronized (this) {
6098            ActivityStack stack = ActivityRecord.getStackLocked(token);
6099            if (stack != null) {
6100                ActivityRecord r =
6101                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6102                if (stopProfiling) {
6103                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6104                        try {
6105                            mProfileFd.close();
6106                        } catch (IOException e) {
6107                        }
6108                        clearProfilerLocked();
6109                    }
6110                }
6111            }
6112        }
6113        Binder.restoreCallingIdentity(origId);
6114    }
6115
6116    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6117        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6118                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6119    }
6120
6121    void enableScreenAfterBoot() {
6122        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6123                SystemClock.uptimeMillis());
6124        mWindowManager.enableScreenAfterBoot();
6125
6126        synchronized (this) {
6127            updateEventDispatchingLocked();
6128        }
6129    }
6130
6131    @Override
6132    public void showBootMessage(final CharSequence msg, final boolean always) {
6133        enforceNotIsolatedCaller("showBootMessage");
6134        mWindowManager.showBootMessage(msg, always);
6135    }
6136
6137    @Override
6138    public void keyguardWaitingForActivityDrawn() {
6139        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6140        final long token = Binder.clearCallingIdentity();
6141        try {
6142            synchronized (this) {
6143                if (DEBUG_LOCKSCREEN) logLockScreen("");
6144                mWindowManager.keyguardWaitingForActivityDrawn();
6145                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6146                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6147                }
6148            }
6149        } finally {
6150            Binder.restoreCallingIdentity(token);
6151        }
6152    }
6153
6154    final void finishBooting() {
6155        synchronized (this) {
6156            if (!mBootAnimationComplete) {
6157                mCallFinishBooting = true;
6158                return;
6159            }
6160            mCallFinishBooting = false;
6161        }
6162
6163        ArraySet<String> completedIsas = new ArraySet<String>();
6164        for (String abi : Build.SUPPORTED_ABIS) {
6165            Process.establishZygoteConnectionForAbi(abi);
6166            final String instructionSet = VMRuntime.getInstructionSet(abi);
6167            if (!completedIsas.contains(instructionSet)) {
6168                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6169                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6170                }
6171                completedIsas.add(instructionSet);
6172            }
6173        }
6174
6175        // Register receivers to handle package update events
6176        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6177
6178        // Let system services know.
6179        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6180
6181        synchronized (this) {
6182            // Ensure that any processes we had put on hold are now started
6183            // up.
6184            final int NP = mProcessesOnHold.size();
6185            if (NP > 0) {
6186                ArrayList<ProcessRecord> procs =
6187                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6188                for (int ip=0; ip<NP; ip++) {
6189                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6190                            + procs.get(ip));
6191                    startProcessLocked(procs.get(ip), "on-hold", null);
6192                }
6193            }
6194
6195            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6196                // Start looking for apps that are abusing wake locks.
6197                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6198                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6199                // Tell anyone interested that we are done booting!
6200                SystemProperties.set("sys.boot_completed", "1");
6201
6202                // And trigger dev.bootcomplete if we are not showing encryption progress
6203                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6204                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6205                    SystemProperties.set("dev.bootcomplete", "1");
6206                }
6207                for (int i=0; i<mStartedUsers.size(); i++) {
6208                    UserStartedState uss = mStartedUsers.valueAt(i);
6209                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6210                        uss.mState = UserStartedState.STATE_RUNNING;
6211                        final int userId = mStartedUsers.keyAt(i);
6212                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6213                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6214                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6215                        broadcastIntentLocked(null, null, intent, null,
6216                                new IIntentReceiver.Stub() {
6217                                    @Override
6218                                    public void performReceive(Intent intent, int resultCode,
6219                                            String data, Bundle extras, boolean ordered,
6220                                            boolean sticky, int sendingUser) {
6221                                        synchronized (ActivityManagerService.this) {
6222                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6223                                                    true, false);
6224                                        }
6225                                    }
6226                                },
6227                                0, null, null,
6228                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6229                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6230                                userId);
6231                    }
6232                }
6233                scheduleStartProfilesLocked();
6234            }
6235        }
6236    }
6237
6238    @Override
6239    public void bootAnimationComplete() {
6240        final boolean callFinishBooting;
6241        synchronized (this) {
6242            callFinishBooting = mCallFinishBooting;
6243            mBootAnimationComplete = true;
6244        }
6245        if (callFinishBooting) {
6246            finishBooting();
6247        }
6248    }
6249
6250    final void ensureBootCompleted() {
6251        boolean booting;
6252        boolean enableScreen;
6253        synchronized (this) {
6254            booting = mBooting;
6255            mBooting = false;
6256            enableScreen = !mBooted;
6257            mBooted = true;
6258        }
6259
6260        if (booting) {
6261            finishBooting();
6262        }
6263
6264        if (enableScreen) {
6265            enableScreenAfterBoot();
6266        }
6267    }
6268
6269    @Override
6270    public final void activityResumed(IBinder token) {
6271        final long origId = Binder.clearCallingIdentity();
6272        synchronized(this) {
6273            ActivityStack stack = ActivityRecord.getStackLocked(token);
6274            if (stack != null) {
6275                ActivityRecord.activityResumedLocked(token);
6276            }
6277        }
6278        Binder.restoreCallingIdentity(origId);
6279    }
6280
6281    @Override
6282    public final void activityPaused(IBinder token) {
6283        final long origId = Binder.clearCallingIdentity();
6284        synchronized(this) {
6285            ActivityStack stack = ActivityRecord.getStackLocked(token);
6286            if (stack != null) {
6287                stack.activityPausedLocked(token, false);
6288            }
6289        }
6290        Binder.restoreCallingIdentity(origId);
6291    }
6292
6293    @Override
6294    public final void activityStopped(IBinder token, Bundle icicle,
6295            PersistableBundle persistentState, CharSequence description) {
6296        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6297
6298        // Refuse possible leaked file descriptors
6299        if (icicle != null && icicle.hasFileDescriptors()) {
6300            throw new IllegalArgumentException("File descriptors passed in Bundle");
6301        }
6302
6303        final long origId = Binder.clearCallingIdentity();
6304
6305        synchronized (this) {
6306            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6307            if (r != null) {
6308                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6309            }
6310        }
6311
6312        trimApplications();
6313
6314        Binder.restoreCallingIdentity(origId);
6315    }
6316
6317    @Override
6318    public final void activityDestroyed(IBinder token) {
6319        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6320        synchronized (this) {
6321            ActivityStack stack = ActivityRecord.getStackLocked(token);
6322            if (stack != null) {
6323                stack.activityDestroyedLocked(token);
6324            }
6325        }
6326    }
6327
6328    @Override
6329    public final void backgroundResourcesReleased(IBinder token) {
6330        final long origId = Binder.clearCallingIdentity();
6331        try {
6332            synchronized (this) {
6333                ActivityStack stack = ActivityRecord.getStackLocked(token);
6334                if (stack != null) {
6335                    stack.backgroundResourcesReleased(token);
6336                }
6337            }
6338        } finally {
6339            Binder.restoreCallingIdentity(origId);
6340        }
6341    }
6342
6343    @Override
6344    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6345        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6346    }
6347
6348    @Override
6349    public final void notifyEnterAnimationComplete(IBinder token) {
6350        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6351    }
6352
6353    @Override
6354    public String getCallingPackage(IBinder token) {
6355        synchronized (this) {
6356            ActivityRecord r = getCallingRecordLocked(token);
6357            return r != null ? r.info.packageName : null;
6358        }
6359    }
6360
6361    @Override
6362    public ComponentName getCallingActivity(IBinder token) {
6363        synchronized (this) {
6364            ActivityRecord r = getCallingRecordLocked(token);
6365            return r != null ? r.intent.getComponent() : null;
6366        }
6367    }
6368
6369    private ActivityRecord getCallingRecordLocked(IBinder token) {
6370        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6371        if (r == null) {
6372            return null;
6373        }
6374        return r.resultTo;
6375    }
6376
6377    @Override
6378    public ComponentName getActivityClassForToken(IBinder token) {
6379        synchronized(this) {
6380            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6381            if (r == null) {
6382                return null;
6383            }
6384            return r.intent.getComponent();
6385        }
6386    }
6387
6388    @Override
6389    public String getPackageForToken(IBinder token) {
6390        synchronized(this) {
6391            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6392            if (r == null) {
6393                return null;
6394            }
6395            return r.packageName;
6396        }
6397    }
6398
6399    @Override
6400    public IIntentSender getIntentSender(int type,
6401            String packageName, IBinder token, String resultWho,
6402            int requestCode, Intent[] intents, String[] resolvedTypes,
6403            int flags, Bundle options, int userId) {
6404        enforceNotIsolatedCaller("getIntentSender");
6405        // Refuse possible leaked file descriptors
6406        if (intents != null) {
6407            if (intents.length < 1) {
6408                throw new IllegalArgumentException("Intents array length must be >= 1");
6409            }
6410            for (int i=0; i<intents.length; i++) {
6411                Intent intent = intents[i];
6412                if (intent != null) {
6413                    if (intent.hasFileDescriptors()) {
6414                        throw new IllegalArgumentException("File descriptors passed in Intent");
6415                    }
6416                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6417                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6418                        throw new IllegalArgumentException(
6419                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6420                    }
6421                    intents[i] = new Intent(intent);
6422                }
6423            }
6424            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6425                throw new IllegalArgumentException(
6426                        "Intent array length does not match resolvedTypes length");
6427            }
6428        }
6429        if (options != null) {
6430            if (options.hasFileDescriptors()) {
6431                throw new IllegalArgumentException("File descriptors passed in options");
6432            }
6433        }
6434
6435        synchronized(this) {
6436            int callingUid = Binder.getCallingUid();
6437            int origUserId = userId;
6438            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6439                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6440                    ALLOW_NON_FULL, "getIntentSender", null);
6441            if (origUserId == UserHandle.USER_CURRENT) {
6442                // We don't want to evaluate this until the pending intent is
6443                // actually executed.  However, we do want to always do the
6444                // security checking for it above.
6445                userId = UserHandle.USER_CURRENT;
6446            }
6447            try {
6448                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6449                    int uid = AppGlobals.getPackageManager()
6450                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6451                    if (!UserHandle.isSameApp(callingUid, uid)) {
6452                        String msg = "Permission Denial: getIntentSender() from pid="
6453                            + Binder.getCallingPid()
6454                            + ", uid=" + Binder.getCallingUid()
6455                            + ", (need uid=" + uid + ")"
6456                            + " is not allowed to send as package " + packageName;
6457                        Slog.w(TAG, msg);
6458                        throw new SecurityException(msg);
6459                    }
6460                }
6461
6462                return getIntentSenderLocked(type, packageName, callingUid, userId,
6463                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6464
6465            } catch (RemoteException e) {
6466                throw new SecurityException(e);
6467            }
6468        }
6469    }
6470
6471    IIntentSender getIntentSenderLocked(int type, String packageName,
6472            int callingUid, int userId, IBinder token, String resultWho,
6473            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6474            Bundle options) {
6475        if (DEBUG_MU)
6476            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6477        ActivityRecord activity = null;
6478        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6479            activity = ActivityRecord.isInStackLocked(token);
6480            if (activity == null) {
6481                return null;
6482            }
6483            if (activity.finishing) {
6484                return null;
6485            }
6486        }
6487
6488        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6489        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6490        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6491        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6492                |PendingIntent.FLAG_UPDATE_CURRENT);
6493
6494        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6495                type, packageName, activity, resultWho,
6496                requestCode, intents, resolvedTypes, flags, options, userId);
6497        WeakReference<PendingIntentRecord> ref;
6498        ref = mIntentSenderRecords.get(key);
6499        PendingIntentRecord rec = ref != null ? ref.get() : null;
6500        if (rec != null) {
6501            if (!cancelCurrent) {
6502                if (updateCurrent) {
6503                    if (rec.key.requestIntent != null) {
6504                        rec.key.requestIntent.replaceExtras(intents != null ?
6505                                intents[intents.length - 1] : null);
6506                    }
6507                    if (intents != null) {
6508                        intents[intents.length-1] = rec.key.requestIntent;
6509                        rec.key.allIntents = intents;
6510                        rec.key.allResolvedTypes = resolvedTypes;
6511                    } else {
6512                        rec.key.allIntents = null;
6513                        rec.key.allResolvedTypes = null;
6514                    }
6515                }
6516                return rec;
6517            }
6518            rec.canceled = true;
6519            mIntentSenderRecords.remove(key);
6520        }
6521        if (noCreate) {
6522            return rec;
6523        }
6524        rec = new PendingIntentRecord(this, key, callingUid);
6525        mIntentSenderRecords.put(key, rec.ref);
6526        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6527            if (activity.pendingResults == null) {
6528                activity.pendingResults
6529                        = new HashSet<WeakReference<PendingIntentRecord>>();
6530            }
6531            activity.pendingResults.add(rec.ref);
6532        }
6533        return rec;
6534    }
6535
6536    @Override
6537    public void cancelIntentSender(IIntentSender sender) {
6538        if (!(sender instanceof PendingIntentRecord)) {
6539            return;
6540        }
6541        synchronized(this) {
6542            PendingIntentRecord rec = (PendingIntentRecord)sender;
6543            try {
6544                int uid = AppGlobals.getPackageManager()
6545                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6546                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6547                    String msg = "Permission Denial: cancelIntentSender() from pid="
6548                        + Binder.getCallingPid()
6549                        + ", uid=" + Binder.getCallingUid()
6550                        + " is not allowed to cancel packges "
6551                        + rec.key.packageName;
6552                    Slog.w(TAG, msg);
6553                    throw new SecurityException(msg);
6554                }
6555            } catch (RemoteException e) {
6556                throw new SecurityException(e);
6557            }
6558            cancelIntentSenderLocked(rec, true);
6559        }
6560    }
6561
6562    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6563        rec.canceled = true;
6564        mIntentSenderRecords.remove(rec.key);
6565        if (cleanActivity && rec.key.activity != null) {
6566            rec.key.activity.pendingResults.remove(rec.ref);
6567        }
6568    }
6569
6570    @Override
6571    public String getPackageForIntentSender(IIntentSender pendingResult) {
6572        if (!(pendingResult instanceof PendingIntentRecord)) {
6573            return null;
6574        }
6575        try {
6576            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6577            return res.key.packageName;
6578        } catch (ClassCastException e) {
6579        }
6580        return null;
6581    }
6582
6583    @Override
6584    public int getUidForIntentSender(IIntentSender sender) {
6585        if (sender instanceof PendingIntentRecord) {
6586            try {
6587                PendingIntentRecord res = (PendingIntentRecord)sender;
6588                return res.uid;
6589            } catch (ClassCastException e) {
6590            }
6591        }
6592        return -1;
6593    }
6594
6595    @Override
6596    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6597        if (!(pendingResult instanceof PendingIntentRecord)) {
6598            return false;
6599        }
6600        try {
6601            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6602            if (res.key.allIntents == null) {
6603                return false;
6604            }
6605            for (int i=0; i<res.key.allIntents.length; i++) {
6606                Intent intent = res.key.allIntents[i];
6607                if (intent.getPackage() != null && intent.getComponent() != null) {
6608                    return false;
6609                }
6610            }
6611            return true;
6612        } catch (ClassCastException e) {
6613        }
6614        return false;
6615    }
6616
6617    @Override
6618    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6619        if (!(pendingResult instanceof PendingIntentRecord)) {
6620            return false;
6621        }
6622        try {
6623            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6624            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6625                return true;
6626            }
6627            return false;
6628        } catch (ClassCastException e) {
6629        }
6630        return false;
6631    }
6632
6633    @Override
6634    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6635        if (!(pendingResult instanceof PendingIntentRecord)) {
6636            return null;
6637        }
6638        try {
6639            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6640            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6641        } catch (ClassCastException e) {
6642        }
6643        return null;
6644    }
6645
6646    @Override
6647    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6648        if (!(pendingResult instanceof PendingIntentRecord)) {
6649            return null;
6650        }
6651        try {
6652            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6653            Intent intent = res.key.requestIntent;
6654            if (intent != null) {
6655                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6656                        || res.lastTagPrefix.equals(prefix))) {
6657                    return res.lastTag;
6658                }
6659                res.lastTagPrefix = prefix;
6660                StringBuilder sb = new StringBuilder(128);
6661                if (prefix != null) {
6662                    sb.append(prefix);
6663                }
6664                if (intent.getAction() != null) {
6665                    sb.append(intent.getAction());
6666                } else if (intent.getComponent() != null) {
6667                    intent.getComponent().appendShortString(sb);
6668                } else {
6669                    sb.append("?");
6670                }
6671                return res.lastTag = sb.toString();
6672            }
6673        } catch (ClassCastException e) {
6674        }
6675        return null;
6676    }
6677
6678    @Override
6679    public void setProcessLimit(int max) {
6680        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6681                "setProcessLimit()");
6682        synchronized (this) {
6683            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6684            mProcessLimitOverride = max;
6685        }
6686        trimApplications();
6687    }
6688
6689    @Override
6690    public int getProcessLimit() {
6691        synchronized (this) {
6692            return mProcessLimitOverride;
6693        }
6694    }
6695
6696    void foregroundTokenDied(ForegroundToken token) {
6697        synchronized (ActivityManagerService.this) {
6698            synchronized (mPidsSelfLocked) {
6699                ForegroundToken cur
6700                    = mForegroundProcesses.get(token.pid);
6701                if (cur != token) {
6702                    return;
6703                }
6704                mForegroundProcesses.remove(token.pid);
6705                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6706                if (pr == null) {
6707                    return;
6708                }
6709                pr.forcingToForeground = null;
6710                updateProcessForegroundLocked(pr, false, false);
6711            }
6712            updateOomAdjLocked();
6713        }
6714    }
6715
6716    @Override
6717    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6718        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6719                "setProcessForeground()");
6720        synchronized(this) {
6721            boolean changed = false;
6722
6723            synchronized (mPidsSelfLocked) {
6724                ProcessRecord pr = mPidsSelfLocked.get(pid);
6725                if (pr == null && isForeground) {
6726                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6727                    return;
6728                }
6729                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6730                if (oldToken != null) {
6731                    oldToken.token.unlinkToDeath(oldToken, 0);
6732                    mForegroundProcesses.remove(pid);
6733                    if (pr != null) {
6734                        pr.forcingToForeground = null;
6735                    }
6736                    changed = true;
6737                }
6738                if (isForeground && token != null) {
6739                    ForegroundToken newToken = new ForegroundToken() {
6740                        @Override
6741                        public void binderDied() {
6742                            foregroundTokenDied(this);
6743                        }
6744                    };
6745                    newToken.pid = pid;
6746                    newToken.token = token;
6747                    try {
6748                        token.linkToDeath(newToken, 0);
6749                        mForegroundProcesses.put(pid, newToken);
6750                        pr.forcingToForeground = token;
6751                        changed = true;
6752                    } catch (RemoteException e) {
6753                        // If the process died while doing this, we will later
6754                        // do the cleanup with the process death link.
6755                    }
6756                }
6757            }
6758
6759            if (changed) {
6760                updateOomAdjLocked();
6761            }
6762        }
6763    }
6764
6765    // =========================================================
6766    // PERMISSIONS
6767    // =========================================================
6768
6769    static class PermissionController extends IPermissionController.Stub {
6770        ActivityManagerService mActivityManagerService;
6771        PermissionController(ActivityManagerService activityManagerService) {
6772            mActivityManagerService = activityManagerService;
6773        }
6774
6775        @Override
6776        public boolean checkPermission(String permission, int pid, int uid) {
6777            return mActivityManagerService.checkPermission(permission, pid,
6778                    uid) == PackageManager.PERMISSION_GRANTED;
6779        }
6780    }
6781
6782    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6783        @Override
6784        public int checkComponentPermission(String permission, int pid, int uid,
6785                int owningUid, boolean exported) {
6786            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6787                    owningUid, exported);
6788        }
6789
6790        @Override
6791        public Object getAMSLock() {
6792            return ActivityManagerService.this;
6793        }
6794    }
6795
6796    /**
6797     * This can be called with or without the global lock held.
6798     */
6799    int checkComponentPermission(String permission, int pid, int uid,
6800            int owningUid, boolean exported) {
6801        // We might be performing an operation on behalf of an indirect binder
6802        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6803        // client identity accordingly before proceeding.
6804        Identity tlsIdentity = sCallerIdentity.get();
6805        if (tlsIdentity != null) {
6806            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6807                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6808            uid = tlsIdentity.uid;
6809            pid = tlsIdentity.pid;
6810        }
6811
6812        if (pid == MY_PID) {
6813            return PackageManager.PERMISSION_GRANTED;
6814        }
6815
6816        return ActivityManager.checkComponentPermission(permission, uid,
6817                owningUid, exported);
6818    }
6819
6820    /**
6821     * As the only public entry point for permissions checking, this method
6822     * can enforce the semantic that requesting a check on a null global
6823     * permission is automatically denied.  (Internally a null permission
6824     * string is used when calling {@link #checkComponentPermission} in cases
6825     * when only uid-based security is needed.)
6826     *
6827     * This can be called with or without the global lock held.
6828     */
6829    @Override
6830    public int checkPermission(String permission, int pid, int uid) {
6831        if (permission == null) {
6832            return PackageManager.PERMISSION_DENIED;
6833        }
6834        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6835    }
6836
6837    /**
6838     * Binder IPC calls go through the public entry point.
6839     * This can be called with or without the global lock held.
6840     */
6841    int checkCallingPermission(String permission) {
6842        return checkPermission(permission,
6843                Binder.getCallingPid(),
6844                UserHandle.getAppId(Binder.getCallingUid()));
6845    }
6846
6847    /**
6848     * This can be called with or without the global lock held.
6849     */
6850    void enforceCallingPermission(String permission, String func) {
6851        if (checkCallingPermission(permission)
6852                == PackageManager.PERMISSION_GRANTED) {
6853            return;
6854        }
6855
6856        String msg = "Permission Denial: " + func + " from pid="
6857                + Binder.getCallingPid()
6858                + ", uid=" + Binder.getCallingUid()
6859                + " requires " + permission;
6860        Slog.w(TAG, msg);
6861        throw new SecurityException(msg);
6862    }
6863
6864    /**
6865     * Determine if UID is holding permissions required to access {@link Uri} in
6866     * the given {@link ProviderInfo}. Final permission checking is always done
6867     * in {@link ContentProvider}.
6868     */
6869    private final boolean checkHoldingPermissionsLocked(
6870            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6871        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6872                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6873        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6874            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6875                    != PERMISSION_GRANTED) {
6876                return false;
6877            }
6878        }
6879        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6880    }
6881
6882    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6883            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6884        if (pi.applicationInfo.uid == uid) {
6885            return true;
6886        } else if (!pi.exported) {
6887            return false;
6888        }
6889
6890        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6891        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6892        try {
6893            // check if target holds top-level <provider> permissions
6894            if (!readMet && pi.readPermission != null && considerUidPermissions
6895                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6896                readMet = true;
6897            }
6898            if (!writeMet && pi.writePermission != null && considerUidPermissions
6899                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6900                writeMet = true;
6901            }
6902
6903            // track if unprotected read/write is allowed; any denied
6904            // <path-permission> below removes this ability
6905            boolean allowDefaultRead = pi.readPermission == null;
6906            boolean allowDefaultWrite = pi.writePermission == null;
6907
6908            // check if target holds any <path-permission> that match uri
6909            final PathPermission[] pps = pi.pathPermissions;
6910            if (pps != null) {
6911                final String path = grantUri.uri.getPath();
6912                int i = pps.length;
6913                while (i > 0 && (!readMet || !writeMet)) {
6914                    i--;
6915                    PathPermission pp = pps[i];
6916                    if (pp.match(path)) {
6917                        if (!readMet) {
6918                            final String pprperm = pp.getReadPermission();
6919                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6920                                    + pprperm + " for " + pp.getPath()
6921                                    + ": match=" + pp.match(path)
6922                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6923                            if (pprperm != null) {
6924                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6925                                        == PERMISSION_GRANTED) {
6926                                    readMet = true;
6927                                } else {
6928                                    allowDefaultRead = false;
6929                                }
6930                            }
6931                        }
6932                        if (!writeMet) {
6933                            final String ppwperm = pp.getWritePermission();
6934                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6935                                    + ppwperm + " for " + pp.getPath()
6936                                    + ": match=" + pp.match(path)
6937                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6938                            if (ppwperm != null) {
6939                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6940                                        == PERMISSION_GRANTED) {
6941                                    writeMet = true;
6942                                } else {
6943                                    allowDefaultWrite = false;
6944                                }
6945                            }
6946                        }
6947                    }
6948                }
6949            }
6950
6951            // grant unprotected <provider> read/write, if not blocked by
6952            // <path-permission> above
6953            if (allowDefaultRead) readMet = true;
6954            if (allowDefaultWrite) writeMet = true;
6955
6956        } catch (RemoteException e) {
6957            return false;
6958        }
6959
6960        return readMet && writeMet;
6961    }
6962
6963    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6964        ProviderInfo pi = null;
6965        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6966        if (cpr != null) {
6967            pi = cpr.info;
6968        } else {
6969            try {
6970                pi = AppGlobals.getPackageManager().resolveContentProvider(
6971                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6972            } catch (RemoteException ex) {
6973            }
6974        }
6975        return pi;
6976    }
6977
6978    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6979        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6980        if (targetUris != null) {
6981            return targetUris.get(grantUri);
6982        }
6983        return null;
6984    }
6985
6986    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6987            String targetPkg, int targetUid, GrantUri grantUri) {
6988        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6989        if (targetUris == null) {
6990            targetUris = Maps.newArrayMap();
6991            mGrantedUriPermissions.put(targetUid, targetUris);
6992        }
6993
6994        UriPermission perm = targetUris.get(grantUri);
6995        if (perm == null) {
6996            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6997            targetUris.put(grantUri, perm);
6998        }
6999
7000        return perm;
7001    }
7002
7003    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7004            final int modeFlags) {
7005        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7006        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7007                : UriPermission.STRENGTH_OWNED;
7008
7009        // Root gets to do everything.
7010        if (uid == 0) {
7011            return true;
7012        }
7013
7014        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7015        if (perms == null) return false;
7016
7017        // First look for exact match
7018        final UriPermission exactPerm = perms.get(grantUri);
7019        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7020            return true;
7021        }
7022
7023        // No exact match, look for prefixes
7024        final int N = perms.size();
7025        for (int i = 0; i < N; i++) {
7026            final UriPermission perm = perms.valueAt(i);
7027            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7028                    && perm.getStrength(modeFlags) >= minStrength) {
7029                return true;
7030            }
7031        }
7032
7033        return false;
7034    }
7035
7036    /**
7037     * @param uri This uri must NOT contain an embedded userId.
7038     * @param userId The userId in which the uri is to be resolved.
7039     */
7040    @Override
7041    public int checkUriPermission(Uri uri, int pid, int uid,
7042            final int modeFlags, int userId) {
7043        enforceNotIsolatedCaller("checkUriPermission");
7044
7045        // Another redirected-binder-call permissions check as in
7046        // {@link checkComponentPermission}.
7047        Identity tlsIdentity = sCallerIdentity.get();
7048        if (tlsIdentity != null) {
7049            uid = tlsIdentity.uid;
7050            pid = tlsIdentity.pid;
7051        }
7052
7053        // Our own process gets to do everything.
7054        if (pid == MY_PID) {
7055            return PackageManager.PERMISSION_GRANTED;
7056        }
7057        synchronized (this) {
7058            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7059                    ? PackageManager.PERMISSION_GRANTED
7060                    : PackageManager.PERMISSION_DENIED;
7061        }
7062    }
7063
7064    /**
7065     * Check if the targetPkg can be granted permission to access uri by
7066     * the callingUid using the given modeFlags.  Throws a security exception
7067     * if callingUid is not allowed to do this.  Returns the uid of the target
7068     * if the URI permission grant should be performed; returns -1 if it is not
7069     * needed (for example targetPkg already has permission to access the URI).
7070     * If you already know the uid of the target, you can supply it in
7071     * lastTargetUid else set that to -1.
7072     */
7073    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7074            final int modeFlags, int lastTargetUid) {
7075        if (!Intent.isAccessUriMode(modeFlags)) {
7076            return -1;
7077        }
7078
7079        if (targetPkg != null) {
7080            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7081                    "Checking grant " + targetPkg + " permission to " + grantUri);
7082        }
7083
7084        final IPackageManager pm = AppGlobals.getPackageManager();
7085
7086        // If this is not a content: uri, we can't do anything with it.
7087        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7088            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7089                    "Can't grant URI permission for non-content URI: " + grantUri);
7090            return -1;
7091        }
7092
7093        final String authority = grantUri.uri.getAuthority();
7094        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7095        if (pi == null) {
7096            Slog.w(TAG, "No content provider found for permission check: " +
7097                    grantUri.uri.toSafeString());
7098            return -1;
7099        }
7100
7101        int targetUid = lastTargetUid;
7102        if (targetUid < 0 && targetPkg != null) {
7103            try {
7104                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7105                if (targetUid < 0) {
7106                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7107                            "Can't grant URI permission no uid for: " + targetPkg);
7108                    return -1;
7109                }
7110            } catch (RemoteException ex) {
7111                return -1;
7112            }
7113        }
7114
7115        if (targetUid >= 0) {
7116            // First...  does the target actually need this permission?
7117            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7118                // No need to grant the target this permission.
7119                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7120                        "Target " + targetPkg + " already has full permission to " + grantUri);
7121                return -1;
7122            }
7123        } else {
7124            // First...  there is no target package, so can anyone access it?
7125            boolean allowed = pi.exported;
7126            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7127                if (pi.readPermission != null) {
7128                    allowed = false;
7129                }
7130            }
7131            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7132                if (pi.writePermission != null) {
7133                    allowed = false;
7134                }
7135            }
7136            if (allowed) {
7137                return -1;
7138            }
7139        }
7140
7141        /* There is a special cross user grant if:
7142         * - The target is on another user.
7143         * - Apps on the current user can access the uri without any uid permissions.
7144         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7145         * grant uri permissions.
7146         */
7147        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7148                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7149                modeFlags, false /*without considering the uid permissions*/);
7150
7151        // Second...  is the provider allowing granting of URI permissions?
7152        if (!specialCrossUserGrant) {
7153            if (!pi.grantUriPermissions) {
7154                throw new SecurityException("Provider " + pi.packageName
7155                        + "/" + pi.name
7156                        + " does not allow granting of Uri permissions (uri "
7157                        + grantUri + ")");
7158            }
7159            if (pi.uriPermissionPatterns != null) {
7160                final int N = pi.uriPermissionPatterns.length;
7161                boolean allowed = false;
7162                for (int i=0; i<N; i++) {
7163                    if (pi.uriPermissionPatterns[i] != null
7164                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7165                        allowed = true;
7166                        break;
7167                    }
7168                }
7169                if (!allowed) {
7170                    throw new SecurityException("Provider " + pi.packageName
7171                            + "/" + pi.name
7172                            + " does not allow granting of permission to path of Uri "
7173                            + grantUri);
7174                }
7175            }
7176        }
7177
7178        // Third...  does the caller itself have permission to access
7179        // this uri?
7180        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7181            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7182                // Require they hold a strong enough Uri permission
7183                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7184                    throw new SecurityException("Uid " + callingUid
7185                            + " does not have permission to uri " + grantUri);
7186                }
7187            }
7188        }
7189        return targetUid;
7190    }
7191
7192    /**
7193     * @param uri This uri must NOT contain an embedded userId.
7194     * @param userId The userId in which the uri is to be resolved.
7195     */
7196    @Override
7197    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7198            final int modeFlags, int userId) {
7199        enforceNotIsolatedCaller("checkGrantUriPermission");
7200        synchronized(this) {
7201            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7202                    new GrantUri(userId, uri, false), modeFlags, -1);
7203        }
7204    }
7205
7206    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7207            final int modeFlags, UriPermissionOwner owner) {
7208        if (!Intent.isAccessUriMode(modeFlags)) {
7209            return;
7210        }
7211
7212        // So here we are: the caller has the assumed permission
7213        // to the uri, and the target doesn't.  Let's now give this to
7214        // the target.
7215
7216        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7217                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7218
7219        final String authority = grantUri.uri.getAuthority();
7220        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7221        if (pi == null) {
7222            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7223            return;
7224        }
7225
7226        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7227            grantUri.prefix = true;
7228        }
7229        final UriPermission perm = findOrCreateUriPermissionLocked(
7230                pi.packageName, targetPkg, targetUid, grantUri);
7231        perm.grantModes(modeFlags, owner);
7232    }
7233
7234    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7235            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7236        if (targetPkg == null) {
7237            throw new NullPointerException("targetPkg");
7238        }
7239        int targetUid;
7240        final IPackageManager pm = AppGlobals.getPackageManager();
7241        try {
7242            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7243        } catch (RemoteException ex) {
7244            return;
7245        }
7246
7247        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7248                targetUid);
7249        if (targetUid < 0) {
7250            return;
7251        }
7252
7253        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7254                owner);
7255    }
7256
7257    static class NeededUriGrants extends ArrayList<GrantUri> {
7258        final String targetPkg;
7259        final int targetUid;
7260        final int flags;
7261
7262        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7263            this.targetPkg = targetPkg;
7264            this.targetUid = targetUid;
7265            this.flags = flags;
7266        }
7267    }
7268
7269    /**
7270     * Like checkGrantUriPermissionLocked, but takes an Intent.
7271     */
7272    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7273            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7274        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7275                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7276                + " clip=" + (intent != null ? intent.getClipData() : null)
7277                + " from " + intent + "; flags=0x"
7278                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7279
7280        if (targetPkg == null) {
7281            throw new NullPointerException("targetPkg");
7282        }
7283
7284        if (intent == null) {
7285            return null;
7286        }
7287        Uri data = intent.getData();
7288        ClipData clip = intent.getClipData();
7289        if (data == null && clip == null) {
7290            return null;
7291        }
7292        // Default userId for uris in the intent (if they don't specify it themselves)
7293        int contentUserHint = intent.getContentUserHint();
7294        if (contentUserHint == UserHandle.USER_CURRENT) {
7295            contentUserHint = UserHandle.getUserId(callingUid);
7296        }
7297        final IPackageManager pm = AppGlobals.getPackageManager();
7298        int targetUid;
7299        if (needed != null) {
7300            targetUid = needed.targetUid;
7301        } else {
7302            try {
7303                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7304            } catch (RemoteException ex) {
7305                return null;
7306            }
7307            if (targetUid < 0) {
7308                if (DEBUG_URI_PERMISSION) {
7309                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7310                            + " on user " + targetUserId);
7311                }
7312                return null;
7313            }
7314        }
7315        if (data != null) {
7316            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7317            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7318                    targetUid);
7319            if (targetUid > 0) {
7320                if (needed == null) {
7321                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7322                }
7323                needed.add(grantUri);
7324            }
7325        }
7326        if (clip != null) {
7327            for (int i=0; i<clip.getItemCount(); i++) {
7328                Uri uri = clip.getItemAt(i).getUri();
7329                if (uri != null) {
7330                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7331                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7332                            targetUid);
7333                    if (targetUid > 0) {
7334                        if (needed == null) {
7335                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7336                        }
7337                        needed.add(grantUri);
7338                    }
7339                } else {
7340                    Intent clipIntent = clip.getItemAt(i).getIntent();
7341                    if (clipIntent != null) {
7342                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7343                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7344                        if (newNeeded != null) {
7345                            needed = newNeeded;
7346                        }
7347                    }
7348                }
7349            }
7350        }
7351
7352        return needed;
7353    }
7354
7355    /**
7356     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7357     */
7358    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7359            UriPermissionOwner owner) {
7360        if (needed != null) {
7361            for (int i=0; i<needed.size(); i++) {
7362                GrantUri grantUri = needed.get(i);
7363                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7364                        grantUri, needed.flags, owner);
7365            }
7366        }
7367    }
7368
7369    void grantUriPermissionFromIntentLocked(int callingUid,
7370            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7371        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7372                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7373        if (needed == null) {
7374            return;
7375        }
7376
7377        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7378    }
7379
7380    /**
7381     * @param uri This uri must NOT contain an embedded userId.
7382     * @param userId The userId in which the uri is to be resolved.
7383     */
7384    @Override
7385    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7386            final int modeFlags, int userId) {
7387        enforceNotIsolatedCaller("grantUriPermission");
7388        GrantUri grantUri = new GrantUri(userId, uri, false);
7389        synchronized(this) {
7390            final ProcessRecord r = getRecordForAppLocked(caller);
7391            if (r == null) {
7392                throw new SecurityException("Unable to find app for caller "
7393                        + caller
7394                        + " when granting permission to uri " + grantUri);
7395            }
7396            if (targetPkg == null) {
7397                throw new IllegalArgumentException("null target");
7398            }
7399            if (grantUri == null) {
7400                throw new IllegalArgumentException("null uri");
7401            }
7402
7403            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7404                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7405                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7406                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7407
7408            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7409                    UserHandle.getUserId(r.uid));
7410        }
7411    }
7412
7413    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7414        if (perm.modeFlags == 0) {
7415            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7416                    perm.targetUid);
7417            if (perms != null) {
7418                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7419                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7420
7421                perms.remove(perm.uri);
7422                if (perms.isEmpty()) {
7423                    mGrantedUriPermissions.remove(perm.targetUid);
7424                }
7425            }
7426        }
7427    }
7428
7429    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7430        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7431
7432        final IPackageManager pm = AppGlobals.getPackageManager();
7433        final String authority = grantUri.uri.getAuthority();
7434        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7435        if (pi == null) {
7436            Slog.w(TAG, "No content provider found for permission revoke: "
7437                    + grantUri.toSafeString());
7438            return;
7439        }
7440
7441        // Does the caller have this permission on the URI?
7442        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7443            // If they don't have direct access to the URI, then revoke any
7444            // ownerless URI permissions that have been granted to them.
7445            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7446            if (perms != null) {
7447                boolean persistChanged = false;
7448                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7449                    final UriPermission perm = it.next();
7450                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7451                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7452                        if (DEBUG_URI_PERMISSION)
7453                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7454                                    " permission to " + perm.uri);
7455                        persistChanged |= perm.revokeModes(
7456                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7457                        if (perm.modeFlags == 0) {
7458                            it.remove();
7459                        }
7460                    }
7461                }
7462                if (perms.isEmpty()) {
7463                    mGrantedUriPermissions.remove(callingUid);
7464                }
7465                if (persistChanged) {
7466                    schedulePersistUriGrants();
7467                }
7468            }
7469            return;
7470        }
7471
7472        boolean persistChanged = false;
7473
7474        // Go through all of the permissions and remove any that match.
7475        int N = mGrantedUriPermissions.size();
7476        for (int i = 0; i < N; i++) {
7477            final int targetUid = mGrantedUriPermissions.keyAt(i);
7478            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7479
7480            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7481                final UriPermission perm = it.next();
7482                if (perm.uri.sourceUserId == grantUri.sourceUserId
7483                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7484                    if (DEBUG_URI_PERMISSION)
7485                        Slog.v(TAG,
7486                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7487                    persistChanged |= perm.revokeModes(
7488                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7489                    if (perm.modeFlags == 0) {
7490                        it.remove();
7491                    }
7492                }
7493            }
7494
7495            if (perms.isEmpty()) {
7496                mGrantedUriPermissions.remove(targetUid);
7497                N--;
7498                i--;
7499            }
7500        }
7501
7502        if (persistChanged) {
7503            schedulePersistUriGrants();
7504        }
7505    }
7506
7507    /**
7508     * @param uri This uri must NOT contain an embedded userId.
7509     * @param userId The userId in which the uri is to be resolved.
7510     */
7511    @Override
7512    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7513            int userId) {
7514        enforceNotIsolatedCaller("revokeUriPermission");
7515        synchronized(this) {
7516            final ProcessRecord r = getRecordForAppLocked(caller);
7517            if (r == null) {
7518                throw new SecurityException("Unable to find app for caller "
7519                        + caller
7520                        + " when revoking permission to uri " + uri);
7521            }
7522            if (uri == null) {
7523                Slog.w(TAG, "revokeUriPermission: null uri");
7524                return;
7525            }
7526
7527            if (!Intent.isAccessUriMode(modeFlags)) {
7528                return;
7529            }
7530
7531            final IPackageManager pm = AppGlobals.getPackageManager();
7532            final String authority = uri.getAuthority();
7533            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7534            if (pi == null) {
7535                Slog.w(TAG, "No content provider found for permission revoke: "
7536                        + uri.toSafeString());
7537                return;
7538            }
7539
7540            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7541        }
7542    }
7543
7544    /**
7545     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7546     * given package.
7547     *
7548     * @param packageName Package name to match, or {@code null} to apply to all
7549     *            packages.
7550     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7551     *            to all users.
7552     * @param persistable If persistable grants should be removed.
7553     */
7554    private void removeUriPermissionsForPackageLocked(
7555            String packageName, int userHandle, boolean persistable) {
7556        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7557            throw new IllegalArgumentException("Must narrow by either package or user");
7558        }
7559
7560        boolean persistChanged = false;
7561
7562        int N = mGrantedUriPermissions.size();
7563        for (int i = 0; i < N; i++) {
7564            final int targetUid = mGrantedUriPermissions.keyAt(i);
7565            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7566
7567            // Only inspect grants matching user
7568            if (userHandle == UserHandle.USER_ALL
7569                    || userHandle == UserHandle.getUserId(targetUid)) {
7570                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7571                    final UriPermission perm = it.next();
7572
7573                    // Only inspect grants matching package
7574                    if (packageName == null || perm.sourcePkg.equals(packageName)
7575                            || perm.targetPkg.equals(packageName)) {
7576                        persistChanged |= perm.revokeModes(persistable
7577                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7578
7579                        // Only remove when no modes remain; any persisted grants
7580                        // will keep this alive.
7581                        if (perm.modeFlags == 0) {
7582                            it.remove();
7583                        }
7584                    }
7585                }
7586
7587                if (perms.isEmpty()) {
7588                    mGrantedUriPermissions.remove(targetUid);
7589                    N--;
7590                    i--;
7591                }
7592            }
7593        }
7594
7595        if (persistChanged) {
7596            schedulePersistUriGrants();
7597        }
7598    }
7599
7600    @Override
7601    public IBinder newUriPermissionOwner(String name) {
7602        enforceNotIsolatedCaller("newUriPermissionOwner");
7603        synchronized(this) {
7604            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7605            return owner.getExternalTokenLocked();
7606        }
7607    }
7608
7609    /**
7610     * @param uri This uri must NOT contain an embedded userId.
7611     * @param sourceUserId The userId in which the uri is to be resolved.
7612     * @param targetUserId The userId of the app that receives the grant.
7613     */
7614    @Override
7615    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7616            final int modeFlags, int sourceUserId, int targetUserId) {
7617        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7618                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7619        synchronized(this) {
7620            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7621            if (owner == null) {
7622                throw new IllegalArgumentException("Unknown owner: " + token);
7623            }
7624            if (fromUid != Binder.getCallingUid()) {
7625                if (Binder.getCallingUid() != Process.myUid()) {
7626                    // Only system code can grant URI permissions on behalf
7627                    // of other users.
7628                    throw new SecurityException("nice try");
7629                }
7630            }
7631            if (targetPkg == null) {
7632                throw new IllegalArgumentException("null target");
7633            }
7634            if (uri == null) {
7635                throw new IllegalArgumentException("null uri");
7636            }
7637
7638            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7639                    modeFlags, owner, targetUserId);
7640        }
7641    }
7642
7643    /**
7644     * @param uri This uri must NOT contain an embedded userId.
7645     * @param userId The userId in which the uri is to be resolved.
7646     */
7647    @Override
7648    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7649        synchronized(this) {
7650            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7651            if (owner == null) {
7652                throw new IllegalArgumentException("Unknown owner: " + token);
7653            }
7654
7655            if (uri == null) {
7656                owner.removeUriPermissionsLocked(mode);
7657            } else {
7658                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7659            }
7660        }
7661    }
7662
7663    private void schedulePersistUriGrants() {
7664        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7665            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7666                    10 * DateUtils.SECOND_IN_MILLIS);
7667        }
7668    }
7669
7670    private void writeGrantedUriPermissions() {
7671        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7672
7673        // Snapshot permissions so we can persist without lock
7674        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7675        synchronized (this) {
7676            final int size = mGrantedUriPermissions.size();
7677            for (int i = 0; i < size; i++) {
7678                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7679                for (UriPermission perm : perms.values()) {
7680                    if (perm.persistedModeFlags != 0) {
7681                        persist.add(perm.snapshot());
7682                    }
7683                }
7684            }
7685        }
7686
7687        FileOutputStream fos = null;
7688        try {
7689            fos = mGrantFile.startWrite();
7690
7691            XmlSerializer out = new FastXmlSerializer();
7692            out.setOutput(fos, "utf-8");
7693            out.startDocument(null, true);
7694            out.startTag(null, TAG_URI_GRANTS);
7695            for (UriPermission.Snapshot perm : persist) {
7696                out.startTag(null, TAG_URI_GRANT);
7697                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7698                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7699                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7700                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7701                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7702                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7703                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7704                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7705                out.endTag(null, TAG_URI_GRANT);
7706            }
7707            out.endTag(null, TAG_URI_GRANTS);
7708            out.endDocument();
7709
7710            mGrantFile.finishWrite(fos);
7711        } catch (IOException e) {
7712            if (fos != null) {
7713                mGrantFile.failWrite(fos);
7714            }
7715        }
7716    }
7717
7718    private void readGrantedUriPermissionsLocked() {
7719        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7720
7721        final long now = System.currentTimeMillis();
7722
7723        FileInputStream fis = null;
7724        try {
7725            fis = mGrantFile.openRead();
7726            final XmlPullParser in = Xml.newPullParser();
7727            in.setInput(fis, null);
7728
7729            int type;
7730            while ((type = in.next()) != END_DOCUMENT) {
7731                final String tag = in.getName();
7732                if (type == START_TAG) {
7733                    if (TAG_URI_GRANT.equals(tag)) {
7734                        final int sourceUserId;
7735                        final int targetUserId;
7736                        final int userHandle = readIntAttribute(in,
7737                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7738                        if (userHandle != UserHandle.USER_NULL) {
7739                            // For backwards compatibility.
7740                            sourceUserId = userHandle;
7741                            targetUserId = userHandle;
7742                        } else {
7743                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7744                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7745                        }
7746                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7747                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7748                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7749                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7750                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7751                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7752
7753                        // Sanity check that provider still belongs to source package
7754                        final ProviderInfo pi = getProviderInfoLocked(
7755                                uri.getAuthority(), sourceUserId);
7756                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7757                            int targetUid = -1;
7758                            try {
7759                                targetUid = AppGlobals.getPackageManager()
7760                                        .getPackageUid(targetPkg, targetUserId);
7761                            } catch (RemoteException e) {
7762                            }
7763                            if (targetUid != -1) {
7764                                final UriPermission perm = findOrCreateUriPermissionLocked(
7765                                        sourcePkg, targetPkg, targetUid,
7766                                        new GrantUri(sourceUserId, uri, prefix));
7767                                perm.initPersistedModes(modeFlags, createdTime);
7768                            }
7769                        } else {
7770                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7771                                    + " but instead found " + pi);
7772                        }
7773                    }
7774                }
7775            }
7776        } catch (FileNotFoundException e) {
7777            // Missing grants is okay
7778        } catch (IOException e) {
7779            Slog.wtf(TAG, "Failed reading Uri grants", e);
7780        } catch (XmlPullParserException e) {
7781            Slog.wtf(TAG, "Failed reading Uri grants", e);
7782        } finally {
7783            IoUtils.closeQuietly(fis);
7784        }
7785    }
7786
7787    /**
7788     * @param uri This uri must NOT contain an embedded userId.
7789     * @param userId The userId in which the uri is to be resolved.
7790     */
7791    @Override
7792    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7793        enforceNotIsolatedCaller("takePersistableUriPermission");
7794
7795        Preconditions.checkFlagsArgument(modeFlags,
7796                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7797
7798        synchronized (this) {
7799            final int callingUid = Binder.getCallingUid();
7800            boolean persistChanged = false;
7801            GrantUri grantUri = new GrantUri(userId, uri, false);
7802
7803            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7804                    new GrantUri(userId, uri, false));
7805            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7806                    new GrantUri(userId, uri, true));
7807
7808            final boolean exactValid = (exactPerm != null)
7809                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7810            final boolean prefixValid = (prefixPerm != null)
7811                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7812
7813            if (!(exactValid || prefixValid)) {
7814                throw new SecurityException("No persistable permission grants found for UID "
7815                        + callingUid + " and Uri " + grantUri.toSafeString());
7816            }
7817
7818            if (exactValid) {
7819                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7820            }
7821            if (prefixValid) {
7822                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7823            }
7824
7825            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7826
7827            if (persistChanged) {
7828                schedulePersistUriGrants();
7829            }
7830        }
7831    }
7832
7833    /**
7834     * @param uri This uri must NOT contain an embedded userId.
7835     * @param userId The userId in which the uri is to be resolved.
7836     */
7837    @Override
7838    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7839        enforceNotIsolatedCaller("releasePersistableUriPermission");
7840
7841        Preconditions.checkFlagsArgument(modeFlags,
7842                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7843
7844        synchronized (this) {
7845            final int callingUid = Binder.getCallingUid();
7846            boolean persistChanged = false;
7847
7848            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7849                    new GrantUri(userId, uri, false));
7850            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7851                    new GrantUri(userId, uri, true));
7852            if (exactPerm == null && prefixPerm == null) {
7853                throw new SecurityException("No permission grants found for UID " + callingUid
7854                        + " and Uri " + uri.toSafeString());
7855            }
7856
7857            if (exactPerm != null) {
7858                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7859                removeUriPermissionIfNeededLocked(exactPerm);
7860            }
7861            if (prefixPerm != null) {
7862                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7863                removeUriPermissionIfNeededLocked(prefixPerm);
7864            }
7865
7866            if (persistChanged) {
7867                schedulePersistUriGrants();
7868            }
7869        }
7870    }
7871
7872    /**
7873     * Prune any older {@link UriPermission} for the given UID until outstanding
7874     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7875     *
7876     * @return if any mutations occured that require persisting.
7877     */
7878    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7879        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7880        if (perms == null) return false;
7881        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7882
7883        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7884        for (UriPermission perm : perms.values()) {
7885            if (perm.persistedModeFlags != 0) {
7886                persisted.add(perm);
7887            }
7888        }
7889
7890        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7891        if (trimCount <= 0) return false;
7892
7893        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7894        for (int i = 0; i < trimCount; i++) {
7895            final UriPermission perm = persisted.get(i);
7896
7897            if (DEBUG_URI_PERMISSION) {
7898                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7899            }
7900
7901            perm.releasePersistableModes(~0);
7902            removeUriPermissionIfNeededLocked(perm);
7903        }
7904
7905        return true;
7906    }
7907
7908    @Override
7909    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7910            String packageName, boolean incoming) {
7911        enforceNotIsolatedCaller("getPersistedUriPermissions");
7912        Preconditions.checkNotNull(packageName, "packageName");
7913
7914        final int callingUid = Binder.getCallingUid();
7915        final IPackageManager pm = AppGlobals.getPackageManager();
7916        try {
7917            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7918            if (packageUid != callingUid) {
7919                throw new SecurityException(
7920                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7921            }
7922        } catch (RemoteException e) {
7923            throw new SecurityException("Failed to verify package name ownership");
7924        }
7925
7926        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7927        synchronized (this) {
7928            if (incoming) {
7929                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7930                        callingUid);
7931                if (perms == null) {
7932                    Slog.w(TAG, "No permission grants found for " + packageName);
7933                } else {
7934                    for (UriPermission perm : perms.values()) {
7935                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7936                            result.add(perm.buildPersistedPublicApiObject());
7937                        }
7938                    }
7939                }
7940            } else {
7941                final int size = mGrantedUriPermissions.size();
7942                for (int i = 0; i < size; i++) {
7943                    final ArrayMap<GrantUri, UriPermission> perms =
7944                            mGrantedUriPermissions.valueAt(i);
7945                    for (UriPermission perm : perms.values()) {
7946                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7947                            result.add(perm.buildPersistedPublicApiObject());
7948                        }
7949                    }
7950                }
7951            }
7952        }
7953        return new ParceledListSlice<android.content.UriPermission>(result);
7954    }
7955
7956    @Override
7957    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7958        synchronized (this) {
7959            ProcessRecord app =
7960                who != null ? getRecordForAppLocked(who) : null;
7961            if (app == null) return;
7962
7963            Message msg = Message.obtain();
7964            msg.what = WAIT_FOR_DEBUGGER_MSG;
7965            msg.obj = app;
7966            msg.arg1 = waiting ? 1 : 0;
7967            mHandler.sendMessage(msg);
7968        }
7969    }
7970
7971    @Override
7972    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7973        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7974        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7975        outInfo.availMem = Process.getFreeMemory();
7976        outInfo.totalMem = Process.getTotalMemory();
7977        outInfo.threshold = homeAppMem;
7978        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7979        outInfo.hiddenAppThreshold = cachedAppMem;
7980        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7981                ProcessList.SERVICE_ADJ);
7982        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7983                ProcessList.VISIBLE_APP_ADJ);
7984        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7985                ProcessList.FOREGROUND_APP_ADJ);
7986    }
7987
7988    // =========================================================
7989    // TASK MANAGEMENT
7990    // =========================================================
7991
7992    @Override
7993    public List<IAppTask> getAppTasks(String callingPackage) {
7994        int callingUid = Binder.getCallingUid();
7995        long ident = Binder.clearCallingIdentity();
7996
7997        synchronized(this) {
7998            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7999            try {
8000                if (localLOGV) Slog.v(TAG, "getAppTasks");
8001
8002                final int N = mRecentTasks.size();
8003                for (int i = 0; i < N; i++) {
8004                    TaskRecord tr = mRecentTasks.get(i);
8005                    // Skip tasks that do not match the caller.  We don't need to verify
8006                    // callingPackage, because we are also limiting to callingUid and know
8007                    // that will limit to the correct security sandbox.
8008                    if (tr.effectiveUid != callingUid) {
8009                        continue;
8010                    }
8011                    Intent intent = tr.getBaseIntent();
8012                    if (intent == null ||
8013                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8014                        continue;
8015                    }
8016                    ActivityManager.RecentTaskInfo taskInfo =
8017                            createRecentTaskInfoFromTaskRecord(tr);
8018                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8019                    list.add(taskImpl);
8020                }
8021            } finally {
8022                Binder.restoreCallingIdentity(ident);
8023            }
8024            return list;
8025        }
8026    }
8027
8028    @Override
8029    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8030        final int callingUid = Binder.getCallingUid();
8031        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8032
8033        synchronized(this) {
8034            if (localLOGV) Slog.v(
8035                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8036
8037            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8038                    callingUid);
8039
8040            // TODO: Improve with MRU list from all ActivityStacks.
8041            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8042        }
8043
8044        return list;
8045    }
8046
8047    TaskRecord getMostRecentTask() {
8048        return mRecentTasks.get(0);
8049    }
8050
8051    /**
8052     * Creates a new RecentTaskInfo from a TaskRecord.
8053     */
8054    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8055        // Update the task description to reflect any changes in the task stack
8056        tr.updateTaskDescription();
8057
8058        // Compose the recent task info
8059        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8060        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8061        rti.persistentId = tr.taskId;
8062        rti.baseIntent = new Intent(tr.getBaseIntent());
8063        rti.origActivity = tr.origActivity;
8064        rti.description = tr.lastDescription;
8065        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8066        rti.userId = tr.userId;
8067        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8068        rti.firstActiveTime = tr.firstActiveTime;
8069        rti.lastActiveTime = tr.lastActiveTime;
8070        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8071        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8072        return rti;
8073    }
8074
8075    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8076        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8077                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8078        if (!allowed) {
8079            if (checkPermission(android.Manifest.permission.GET_TASKS,
8080                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8081                // Temporary compatibility: some existing apps on the system image may
8082                // still be requesting the old permission and not switched to the new
8083                // one; if so, we'll still allow them full access.  This means we need
8084                // to see if they are holding the old permission and are a system app.
8085                try {
8086                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8087                        allowed = true;
8088                        Slog.w(TAG, caller + ": caller " + callingUid
8089                                + " is using old GET_TASKS but privileged; allowing");
8090                    }
8091                } catch (RemoteException e) {
8092                }
8093            }
8094        }
8095        if (!allowed) {
8096            Slog.w(TAG, caller + ": caller " + callingUid
8097                    + " does not hold GET_TASKS; limiting output");
8098        }
8099        return allowed;
8100    }
8101
8102    @Override
8103    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8104        final int callingUid = Binder.getCallingUid();
8105        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8106                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8107
8108        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8109        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8110        synchronized (this) {
8111            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8112                    callingUid);
8113            final boolean detailed = checkCallingPermission(
8114                    android.Manifest.permission.GET_DETAILED_TASKS)
8115                    == PackageManager.PERMISSION_GRANTED;
8116
8117            final int N = mRecentTasks.size();
8118            ArrayList<ActivityManager.RecentTaskInfo> res
8119                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8120                            maxNum < N ? maxNum : N);
8121
8122            final Set<Integer> includedUsers;
8123            if (includeProfiles) {
8124                includedUsers = getProfileIdsLocked(userId);
8125            } else {
8126                includedUsers = new HashSet<Integer>();
8127            }
8128            includedUsers.add(Integer.valueOf(userId));
8129
8130            for (int i=0; i<N && maxNum > 0; i++) {
8131                TaskRecord tr = mRecentTasks.get(i);
8132                // Only add calling user or related users recent tasks
8133                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8134                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8135                    continue;
8136                }
8137
8138                // Return the entry if desired by the caller.  We always return
8139                // the first entry, because callers always expect this to be the
8140                // foreground app.  We may filter others if the caller has
8141                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8142                // we should exclude the entry.
8143
8144                if (i == 0
8145                        || withExcluded
8146                        || (tr.intent == null)
8147                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8148                                == 0)) {
8149                    if (!allowed) {
8150                        // If the caller doesn't have the GET_TASKS permission, then only
8151                        // allow them to see a small subset of tasks -- their own and home.
8152                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8153                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8154                            continue;
8155                        }
8156                    }
8157                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8158                        if (tr.stack != null && tr.stack.isHomeStack()) {
8159                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8160                            continue;
8161                        }
8162                    }
8163                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8164                        // Don't include auto remove tasks that are finished or finishing.
8165                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8166                                + tr);
8167                        continue;
8168                    }
8169                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8170                            && !tr.isAvailable) {
8171                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8172                        continue;
8173                    }
8174
8175                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8176                    if (!detailed) {
8177                        rti.baseIntent.replaceExtras((Bundle)null);
8178                    }
8179
8180                    res.add(rti);
8181                    maxNum--;
8182                }
8183            }
8184            return res;
8185        }
8186    }
8187
8188    private TaskRecord taskForIdLocked(int id) {
8189        final TaskRecord task = recentTaskForIdLocked(id);
8190        if (task != null) {
8191            return task;
8192        }
8193
8194        // Don't give up. Sometimes it just hasn't made it to recents yet.
8195        return mStackSupervisor.anyTaskForIdLocked(id);
8196    }
8197
8198    private TaskRecord recentTaskForIdLocked(int id) {
8199        final int N = mRecentTasks.size();
8200            for (int i=0; i<N; i++) {
8201                TaskRecord tr = mRecentTasks.get(i);
8202                if (tr.taskId == id) {
8203                    return tr;
8204                }
8205            }
8206            return null;
8207    }
8208
8209    @Override
8210    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8211        synchronized (this) {
8212            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8213                    "getTaskThumbnail()");
8214            TaskRecord tr = recentTaskForIdLocked(id);
8215            if (tr != null) {
8216                return tr.getTaskThumbnailLocked();
8217            }
8218        }
8219        return null;
8220    }
8221
8222    @Override
8223    public int addAppTask(IBinder activityToken, Intent intent,
8224            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8225        final int callingUid = Binder.getCallingUid();
8226        final long callingIdent = Binder.clearCallingIdentity();
8227
8228        try {
8229            synchronized (this) {
8230                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8231                if (r == null) {
8232                    throw new IllegalArgumentException("Activity does not exist; token="
8233                            + activityToken);
8234                }
8235                ComponentName comp = intent.getComponent();
8236                if (comp == null) {
8237                    throw new IllegalArgumentException("Intent " + intent
8238                            + " must specify explicit component");
8239                }
8240                if (thumbnail.getWidth() != mThumbnailWidth
8241                        || thumbnail.getHeight() != mThumbnailHeight) {
8242                    throw new IllegalArgumentException("Bad thumbnail size: got "
8243                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8244                            + mThumbnailWidth + "x" + mThumbnailHeight);
8245                }
8246                if (intent.getSelector() != null) {
8247                    intent.setSelector(null);
8248                }
8249                if (intent.getSourceBounds() != null) {
8250                    intent.setSourceBounds(null);
8251                }
8252                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8253                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8254                        // The caller has added this as an auto-remove task...  that makes no
8255                        // sense, so turn off auto-remove.
8256                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8257                    }
8258                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8259                    // Must be a new task.
8260                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8261                }
8262                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8263                    mLastAddedTaskActivity = null;
8264                }
8265                ActivityInfo ainfo = mLastAddedTaskActivity;
8266                if (ainfo == null) {
8267                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8268                            comp, 0, UserHandle.getUserId(callingUid));
8269                    if (ainfo.applicationInfo.uid != callingUid) {
8270                        throw new SecurityException(
8271                                "Can't add task for another application: target uid="
8272                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8273                    }
8274                }
8275
8276                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8277                        intent, description);
8278
8279                int trimIdx = trimRecentsForTask(task, false);
8280                if (trimIdx >= 0) {
8281                    // If this would have caused a trim, then we'll abort because that
8282                    // means it would be added at the end of the list but then just removed.
8283                    return -1;
8284                }
8285
8286                final int N = mRecentTasks.size();
8287                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8288                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8289                    tr.removedFromRecents(mTaskPersister);
8290                }
8291
8292                task.inRecents = true;
8293                mRecentTasks.add(task);
8294                r.task.stack.addTask(task, false, false);
8295
8296                task.setLastThumbnail(thumbnail);
8297                task.freeLastThumbnail();
8298
8299                return task.taskId;
8300            }
8301        } finally {
8302            Binder.restoreCallingIdentity(callingIdent);
8303        }
8304    }
8305
8306    @Override
8307    public Point getAppTaskThumbnailSize() {
8308        synchronized (this) {
8309            return new Point(mThumbnailWidth,  mThumbnailHeight);
8310        }
8311    }
8312
8313    @Override
8314    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8315        synchronized (this) {
8316            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8317            if (r != null) {
8318                r.setTaskDescription(td);
8319                r.task.updateTaskDescription();
8320            }
8321        }
8322    }
8323
8324    @Override
8325    public Bitmap getTaskDescriptionIcon(String filename) {
8326        if (!FileUtils.isValidExtFilename(filename)
8327                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8328            throw new IllegalArgumentException("Bad filename: " + filename);
8329        }
8330        return mTaskPersister.getTaskDescriptionIcon(filename);
8331    }
8332
8333    @Override
8334    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8335            throws RemoteException {
8336        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8337                opts.getCustomInPlaceResId() == 0) {
8338            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8339                    "with valid animation");
8340        }
8341        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8342        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8343                opts.getCustomInPlaceResId());
8344        mWindowManager.executeAppTransition();
8345    }
8346
8347    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8348        mRecentTasks.remove(tr);
8349        tr.removedFromRecents(mTaskPersister);
8350        ComponentName component = tr.getBaseIntent().getComponent();
8351        if (component == null) {
8352            Slog.w(TAG, "No component for base intent of task: " + tr);
8353            return;
8354        }
8355
8356        if (!killProcess) {
8357            return;
8358        }
8359
8360        // Determine if the process(es) for this task should be killed.
8361        final String pkg = component.getPackageName();
8362        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8363        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8364        for (int i = 0; i < pmap.size(); i++) {
8365
8366            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8367            for (int j = 0; j < uids.size(); j++) {
8368                ProcessRecord proc = uids.valueAt(j);
8369                if (proc.userId != tr.userId) {
8370                    // Don't kill process for a different user.
8371                    continue;
8372                }
8373                if (proc == mHomeProcess) {
8374                    // Don't kill the home process along with tasks from the same package.
8375                    continue;
8376                }
8377                if (!proc.pkgList.containsKey(pkg)) {
8378                    // Don't kill process that is not associated with this task.
8379                    continue;
8380                }
8381
8382                for (int k = 0; k < proc.activities.size(); k++) {
8383                    TaskRecord otherTask = proc.activities.get(k).task;
8384                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8385                        // Don't kill process(es) that has an activity in a different task that is
8386                        // also in recents.
8387                        return;
8388                    }
8389                }
8390
8391                // Add process to kill list.
8392                procsToKill.add(proc);
8393            }
8394        }
8395
8396        // Find any running services associated with this app and stop if needed.
8397        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8398
8399        // Kill the running processes.
8400        for (int i = 0; i < procsToKill.size(); i++) {
8401            ProcessRecord pr = procsToKill.get(i);
8402            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8403                pr.kill("remove task", true);
8404            } else {
8405                pr.waitingToKill = "remove task";
8406            }
8407        }
8408    }
8409
8410    /**
8411     * Removes the task with the specified task id.
8412     *
8413     * @param taskId Identifier of the task to be removed.
8414     * @param killProcess Kill any process associated with the task if possible.
8415     * @return Returns true if the given task was found and removed.
8416     */
8417    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8418        TaskRecord tr = taskForIdLocked(taskId);
8419        if (tr != null) {
8420            tr.removeTaskActivitiesLocked();
8421            cleanUpRemovedTaskLocked(tr, killProcess);
8422            if (tr.isPersistable) {
8423                notifyTaskPersisterLocked(null, true);
8424            }
8425            return true;
8426        }
8427        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8428        return false;
8429    }
8430
8431    @Override
8432    public boolean removeTask(int taskId) {
8433        synchronized (this) {
8434            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8435                    "removeTask()");
8436            long ident = Binder.clearCallingIdentity();
8437            try {
8438                return removeTaskByIdLocked(taskId, true);
8439            } finally {
8440                Binder.restoreCallingIdentity(ident);
8441            }
8442        }
8443    }
8444
8445    /**
8446     * TODO: Add mController hook
8447     */
8448    @Override
8449    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8450        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8451                "moveTaskToFront()");
8452
8453        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8454        synchronized(this) {
8455            moveTaskToFrontLocked(taskId, flags, options);
8456        }
8457    }
8458
8459    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8460        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8461                Binder.getCallingUid(), -1, -1, "Task to front")) {
8462            ActivityOptions.abort(options);
8463            return;
8464        }
8465        final long origId = Binder.clearCallingIdentity();
8466        try {
8467            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8468            if (task == null) {
8469                return;
8470            }
8471            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8472                mStackSupervisor.showLockTaskToast();
8473                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8474                return;
8475            }
8476            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8477            if (prev != null && prev.isRecentsActivity()) {
8478                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8479            }
8480            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8481        } finally {
8482            Binder.restoreCallingIdentity(origId);
8483        }
8484        ActivityOptions.abort(options);
8485    }
8486
8487    @Override
8488    public void moveTaskToBack(int taskId) {
8489        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8490                "moveTaskToBack()");
8491
8492        synchronized(this) {
8493            TaskRecord tr = taskForIdLocked(taskId);
8494            if (tr != null) {
8495                if (tr == mStackSupervisor.mLockTaskModeTask) {
8496                    mStackSupervisor.showLockTaskToast();
8497                    return;
8498                }
8499                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8500                ActivityStack stack = tr.stack;
8501                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8502                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8503                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8504                        return;
8505                    }
8506                }
8507                final long origId = Binder.clearCallingIdentity();
8508                try {
8509                    stack.moveTaskToBackLocked(taskId, null);
8510                } finally {
8511                    Binder.restoreCallingIdentity(origId);
8512                }
8513            }
8514        }
8515    }
8516
8517    /**
8518     * Moves an activity, and all of the other activities within the same task, to the bottom
8519     * of the history stack.  The activity's order within the task is unchanged.
8520     *
8521     * @param token A reference to the activity we wish to move
8522     * @param nonRoot If false then this only works if the activity is the root
8523     *                of a task; if true it will work for any activity in a task.
8524     * @return Returns true if the move completed, false if not.
8525     */
8526    @Override
8527    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8528        enforceNotIsolatedCaller("moveActivityTaskToBack");
8529        synchronized(this) {
8530            final long origId = Binder.clearCallingIdentity();
8531            try {
8532                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8533                if (taskId >= 0) {
8534                    if ((mStackSupervisor.mLockTaskModeTask != null)
8535                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8536                        mStackSupervisor.showLockTaskToast();
8537                        return false;
8538                    }
8539                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8540                }
8541            } finally {
8542                Binder.restoreCallingIdentity(origId);
8543            }
8544        }
8545        return false;
8546    }
8547
8548    @Override
8549    public void moveTaskBackwards(int task) {
8550        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8551                "moveTaskBackwards()");
8552
8553        synchronized(this) {
8554            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8555                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8556                return;
8557            }
8558            final long origId = Binder.clearCallingIdentity();
8559            moveTaskBackwardsLocked(task);
8560            Binder.restoreCallingIdentity(origId);
8561        }
8562    }
8563
8564    private final void moveTaskBackwardsLocked(int task) {
8565        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8566    }
8567
8568    @Override
8569    public IBinder getHomeActivityToken() throws RemoteException {
8570        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8571                "getHomeActivityToken()");
8572        synchronized (this) {
8573            return mStackSupervisor.getHomeActivityToken();
8574        }
8575    }
8576
8577    @Override
8578    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8579            IActivityContainerCallback callback) throws RemoteException {
8580        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8581                "createActivityContainer()");
8582        synchronized (this) {
8583            if (parentActivityToken == null) {
8584                throw new IllegalArgumentException("parent token must not be null");
8585            }
8586            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8587            if (r == null) {
8588                return null;
8589            }
8590            if (callback == null) {
8591                throw new IllegalArgumentException("callback must not be null");
8592            }
8593            return mStackSupervisor.createActivityContainer(r, callback);
8594        }
8595    }
8596
8597    @Override
8598    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8599        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8600                "deleteActivityContainer()");
8601        synchronized (this) {
8602            mStackSupervisor.deleteActivityContainer(container);
8603        }
8604    }
8605
8606    @Override
8607    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8608            throws RemoteException {
8609        synchronized (this) {
8610            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8611            if (stack != null) {
8612                return stack.mActivityContainer;
8613            }
8614            return null;
8615        }
8616    }
8617
8618    @Override
8619    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8620        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8621                "moveTaskToStack()");
8622        if (stackId == HOME_STACK_ID) {
8623            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8624                    new RuntimeException("here").fillInStackTrace());
8625        }
8626        synchronized (this) {
8627            long ident = Binder.clearCallingIdentity();
8628            try {
8629                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8630                        + stackId + " toTop=" + toTop);
8631                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8632            } finally {
8633                Binder.restoreCallingIdentity(ident);
8634            }
8635        }
8636    }
8637
8638    @Override
8639    public void resizeStack(int stackBoxId, Rect bounds) {
8640        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8641                "resizeStackBox()");
8642        long ident = Binder.clearCallingIdentity();
8643        try {
8644            mWindowManager.resizeStack(stackBoxId, bounds);
8645        } finally {
8646            Binder.restoreCallingIdentity(ident);
8647        }
8648    }
8649
8650    @Override
8651    public List<StackInfo> getAllStackInfos() {
8652        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8653                "getAllStackInfos()");
8654        long ident = Binder.clearCallingIdentity();
8655        try {
8656            synchronized (this) {
8657                return mStackSupervisor.getAllStackInfosLocked();
8658            }
8659        } finally {
8660            Binder.restoreCallingIdentity(ident);
8661        }
8662    }
8663
8664    @Override
8665    public StackInfo getStackInfo(int stackId) {
8666        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8667                "getStackInfo()");
8668        long ident = Binder.clearCallingIdentity();
8669        try {
8670            synchronized (this) {
8671                return mStackSupervisor.getStackInfoLocked(stackId);
8672            }
8673        } finally {
8674            Binder.restoreCallingIdentity(ident);
8675        }
8676    }
8677
8678    @Override
8679    public boolean isInHomeStack(int taskId) {
8680        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8681                "getStackInfo()");
8682        long ident = Binder.clearCallingIdentity();
8683        try {
8684            synchronized (this) {
8685                TaskRecord tr = taskForIdLocked(taskId);
8686                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8687            }
8688        } finally {
8689            Binder.restoreCallingIdentity(ident);
8690        }
8691    }
8692
8693    @Override
8694    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8695        synchronized(this) {
8696            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8697        }
8698    }
8699
8700    private boolean isLockTaskAuthorized(String pkg) {
8701        final DevicePolicyManager dpm = (DevicePolicyManager)
8702                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8703        try {
8704            int uid = mContext.getPackageManager().getPackageUid(pkg,
8705                    Binder.getCallingUserHandle().getIdentifier());
8706            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8707        } catch (NameNotFoundException e) {
8708            return false;
8709        }
8710    }
8711
8712    void startLockTaskMode(TaskRecord task) {
8713        final String pkg;
8714        synchronized (this) {
8715            pkg = task.intent.getComponent().getPackageName();
8716        }
8717        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8718        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8719            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8720                    StatusBarManagerInternal.class);
8721            if (statusBarManager != null) {
8722                statusBarManager.showScreenPinningRequest();
8723            }
8724            return;
8725        }
8726        long ident = Binder.clearCallingIdentity();
8727        try {
8728            synchronized (this) {
8729                // Since we lost lock on task, make sure it is still there.
8730                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8731                if (task != null) {
8732                    if (!isSystemInitiated
8733                            && ((mStackSupervisor.getFocusedStack() == null)
8734                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8735                        throw new IllegalArgumentException("Invalid task, not in foreground");
8736                    }
8737                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8738                }
8739            }
8740        } finally {
8741            Binder.restoreCallingIdentity(ident);
8742        }
8743    }
8744
8745    @Override
8746    public void startLockTaskMode(int taskId) {
8747        final TaskRecord task;
8748        long ident = Binder.clearCallingIdentity();
8749        try {
8750            synchronized (this) {
8751                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8752            }
8753        } finally {
8754            Binder.restoreCallingIdentity(ident);
8755        }
8756        if (task != null) {
8757            startLockTaskMode(task);
8758        }
8759    }
8760
8761    @Override
8762    public void startLockTaskMode(IBinder token) {
8763        final TaskRecord task;
8764        long ident = Binder.clearCallingIdentity();
8765        try {
8766            synchronized (this) {
8767                final ActivityRecord r = ActivityRecord.forToken(token);
8768                if (r == null) {
8769                    return;
8770                }
8771                task = r.task;
8772            }
8773        } finally {
8774            Binder.restoreCallingIdentity(ident);
8775        }
8776        if (task != null) {
8777            startLockTaskMode(task);
8778        }
8779    }
8780
8781    @Override
8782    public void startLockTaskModeOnCurrent() throws RemoteException {
8783        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8784                "startLockTaskModeOnCurrent");
8785        long ident = Binder.clearCallingIdentity();
8786        try {
8787            ActivityRecord r = null;
8788            synchronized (this) {
8789                r = mStackSupervisor.topRunningActivityLocked();
8790            }
8791            startLockTaskMode(r.task);
8792        } finally {
8793            Binder.restoreCallingIdentity(ident);
8794        }
8795    }
8796
8797    @Override
8798    public void stopLockTaskMode() {
8799        // Verify that the user matches the package of the intent for the TaskRecord
8800        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8801        // and stopLockTaskMode.
8802        final int callingUid = Binder.getCallingUid();
8803        if (callingUid != Process.SYSTEM_UID) {
8804            try {
8805                String pkg =
8806                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8807                int uid = mContext.getPackageManager().getPackageUid(pkg,
8808                        Binder.getCallingUserHandle().getIdentifier());
8809                if (uid != callingUid) {
8810                    throw new SecurityException("Invalid uid, expected " + uid);
8811                }
8812            } catch (NameNotFoundException e) {
8813                Log.d(TAG, "stopLockTaskMode " + e);
8814                return;
8815            }
8816        }
8817        long ident = Binder.clearCallingIdentity();
8818        try {
8819            Log.d(TAG, "stopLockTaskMode");
8820            // Stop lock task
8821            synchronized (this) {
8822                mStackSupervisor.setLockTaskModeLocked(null, false);
8823            }
8824        } finally {
8825            Binder.restoreCallingIdentity(ident);
8826        }
8827    }
8828
8829    @Override
8830    public void stopLockTaskModeOnCurrent() throws RemoteException {
8831        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8832                "stopLockTaskModeOnCurrent");
8833        long ident = Binder.clearCallingIdentity();
8834        try {
8835            stopLockTaskMode();
8836        } finally {
8837            Binder.restoreCallingIdentity(ident);
8838        }
8839    }
8840
8841    @Override
8842    public boolean isInLockTaskMode() {
8843        synchronized (this) {
8844            return mStackSupervisor.isInLockTaskMode();
8845        }
8846    }
8847
8848    // =========================================================
8849    // CONTENT PROVIDERS
8850    // =========================================================
8851
8852    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8853        List<ProviderInfo> providers = null;
8854        try {
8855            providers = AppGlobals.getPackageManager().
8856                queryContentProviders(app.processName, app.uid,
8857                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8858        } catch (RemoteException ex) {
8859        }
8860        if (DEBUG_MU)
8861            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8862        int userId = app.userId;
8863        if (providers != null) {
8864            int N = providers.size();
8865            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8866            for (int i=0; i<N; i++) {
8867                ProviderInfo cpi =
8868                    (ProviderInfo)providers.get(i);
8869                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8870                        cpi.name, cpi.flags);
8871                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8872                    // This is a singleton provider, but a user besides the
8873                    // default user is asking to initialize a process it runs
8874                    // in...  well, no, it doesn't actually run in this process,
8875                    // it runs in the process of the default user.  Get rid of it.
8876                    providers.remove(i);
8877                    N--;
8878                    i--;
8879                    continue;
8880                }
8881
8882                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8883                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8884                if (cpr == null) {
8885                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8886                    mProviderMap.putProviderByClass(comp, cpr);
8887                }
8888                if (DEBUG_MU)
8889                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8890                app.pubProviders.put(cpi.name, cpr);
8891                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8892                    // Don't add this if it is a platform component that is marked
8893                    // to run in multiple processes, because this is actually
8894                    // part of the framework so doesn't make sense to track as a
8895                    // separate apk in the process.
8896                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8897                            mProcessStats);
8898                }
8899                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8900            }
8901        }
8902        return providers;
8903    }
8904
8905    /**
8906     * Check if {@link ProcessRecord} has a possible chance at accessing the
8907     * given {@link ProviderInfo}. Final permission checking is always done
8908     * in {@link ContentProvider}.
8909     */
8910    private final String checkContentProviderPermissionLocked(
8911            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8912        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8913        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8914        boolean checkedGrants = false;
8915        if (checkUser) {
8916            // Looking for cross-user grants before enforcing the typical cross-users permissions
8917            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8918            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8919                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8920                    return null;
8921                }
8922                checkedGrants = true;
8923            }
8924            userId = handleIncomingUser(callingPid, callingUid, userId,
8925                    false, ALLOW_NON_FULL,
8926                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8927            if (userId != tmpTargetUserId) {
8928                // When we actually went to determine the final targer user ID, this ended
8929                // up different than our initial check for the authority.  This is because
8930                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8931                // SELF.  So we need to re-check the grants again.
8932                checkedGrants = false;
8933            }
8934        }
8935        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8936                cpi.applicationInfo.uid, cpi.exported)
8937                == PackageManager.PERMISSION_GRANTED) {
8938            return null;
8939        }
8940        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8941                cpi.applicationInfo.uid, cpi.exported)
8942                == PackageManager.PERMISSION_GRANTED) {
8943            return null;
8944        }
8945
8946        PathPermission[] pps = cpi.pathPermissions;
8947        if (pps != null) {
8948            int i = pps.length;
8949            while (i > 0) {
8950                i--;
8951                PathPermission pp = pps[i];
8952                String pprperm = pp.getReadPermission();
8953                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8954                        cpi.applicationInfo.uid, cpi.exported)
8955                        == PackageManager.PERMISSION_GRANTED) {
8956                    return null;
8957                }
8958                String ppwperm = pp.getWritePermission();
8959                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8960                        cpi.applicationInfo.uid, cpi.exported)
8961                        == PackageManager.PERMISSION_GRANTED) {
8962                    return null;
8963                }
8964            }
8965        }
8966        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8967            return null;
8968        }
8969
8970        String msg;
8971        if (!cpi.exported) {
8972            msg = "Permission Denial: opening provider " + cpi.name
8973                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8974                    + ", uid=" + callingUid + ") that is not exported from uid "
8975                    + cpi.applicationInfo.uid;
8976        } else {
8977            msg = "Permission Denial: opening provider " + cpi.name
8978                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8979                    + ", uid=" + callingUid + ") requires "
8980                    + cpi.readPermission + " or " + cpi.writePermission;
8981        }
8982        Slog.w(TAG, msg);
8983        return msg;
8984    }
8985
8986    /**
8987     * Returns if the ContentProvider has granted a uri to callingUid
8988     */
8989    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8990        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8991        if (perms != null) {
8992            for (int i=perms.size()-1; i>=0; i--) {
8993                GrantUri grantUri = perms.keyAt(i);
8994                if (grantUri.sourceUserId == userId || !checkUser) {
8995                    if (matchesProvider(grantUri.uri, cpi)) {
8996                        return true;
8997                    }
8998                }
8999            }
9000        }
9001        return false;
9002    }
9003
9004    /**
9005     * Returns true if the uri authority is one of the authorities specified in the provider.
9006     */
9007    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9008        String uriAuth = uri.getAuthority();
9009        String cpiAuth = cpi.authority;
9010        if (cpiAuth.indexOf(';') == -1) {
9011            return cpiAuth.equals(uriAuth);
9012        }
9013        String[] cpiAuths = cpiAuth.split(";");
9014        int length = cpiAuths.length;
9015        for (int i = 0; i < length; i++) {
9016            if (cpiAuths[i].equals(uriAuth)) return true;
9017        }
9018        return false;
9019    }
9020
9021    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9022            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9023        if (r != null) {
9024            for (int i=0; i<r.conProviders.size(); i++) {
9025                ContentProviderConnection conn = r.conProviders.get(i);
9026                if (conn.provider == cpr) {
9027                    if (DEBUG_PROVIDER) Slog.v(TAG,
9028                            "Adding provider requested by "
9029                            + r.processName + " from process "
9030                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9031                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9032                    if (stable) {
9033                        conn.stableCount++;
9034                        conn.numStableIncs++;
9035                    } else {
9036                        conn.unstableCount++;
9037                        conn.numUnstableIncs++;
9038                    }
9039                    return conn;
9040                }
9041            }
9042            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9043            if (stable) {
9044                conn.stableCount = 1;
9045                conn.numStableIncs = 1;
9046            } else {
9047                conn.unstableCount = 1;
9048                conn.numUnstableIncs = 1;
9049            }
9050            cpr.connections.add(conn);
9051            r.conProviders.add(conn);
9052            return conn;
9053        }
9054        cpr.addExternalProcessHandleLocked(externalProcessToken);
9055        return null;
9056    }
9057
9058    boolean decProviderCountLocked(ContentProviderConnection conn,
9059            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9060        if (conn != null) {
9061            cpr = conn.provider;
9062            if (DEBUG_PROVIDER) Slog.v(TAG,
9063                    "Removing provider requested by "
9064                    + conn.client.processName + " from process "
9065                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9066                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9067            if (stable) {
9068                conn.stableCount--;
9069            } else {
9070                conn.unstableCount--;
9071            }
9072            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9073                cpr.connections.remove(conn);
9074                conn.client.conProviders.remove(conn);
9075                return true;
9076            }
9077            return false;
9078        }
9079        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9080        return false;
9081    }
9082
9083    private void checkTime(long startTime, String where) {
9084        long now = SystemClock.elapsedRealtime();
9085        if ((now-startTime) > 1000) {
9086            // If we are taking more than a second, log about it.
9087            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9088        }
9089    }
9090
9091    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9092            String name, IBinder token, boolean stable, int userId) {
9093        ContentProviderRecord cpr;
9094        ContentProviderConnection conn = null;
9095        ProviderInfo cpi = null;
9096
9097        synchronized(this) {
9098            long startTime = SystemClock.elapsedRealtime();
9099
9100            ProcessRecord r = null;
9101            if (caller != null) {
9102                r = getRecordForAppLocked(caller);
9103                if (r == null) {
9104                    throw new SecurityException(
9105                            "Unable to find app for caller " + caller
9106                          + " (pid=" + Binder.getCallingPid()
9107                          + ") when getting content provider " + name);
9108                }
9109            }
9110
9111            boolean checkCrossUser = true;
9112
9113            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9114
9115            // First check if this content provider has been published...
9116            cpr = mProviderMap.getProviderByName(name, userId);
9117            // If that didn't work, check if it exists for user 0 and then
9118            // verify that it's a singleton provider before using it.
9119            if (cpr == null && userId != UserHandle.USER_OWNER) {
9120                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9121                if (cpr != null) {
9122                    cpi = cpr.info;
9123                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9124                            cpi.name, cpi.flags)
9125                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9126                        userId = UserHandle.USER_OWNER;
9127                        checkCrossUser = false;
9128                    } else {
9129                        cpr = null;
9130                        cpi = null;
9131                    }
9132                }
9133            }
9134
9135            boolean providerRunning = cpr != null;
9136            if (providerRunning) {
9137                cpi = cpr.info;
9138                String msg;
9139                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9140                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9141                        != null) {
9142                    throw new SecurityException(msg);
9143                }
9144                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9145
9146                if (r != null && cpr.canRunHere(r)) {
9147                    // This provider has been published or is in the process
9148                    // of being published...  but it is also allowed to run
9149                    // in the caller's process, so don't make a connection
9150                    // and just let the caller instantiate its own instance.
9151                    ContentProviderHolder holder = cpr.newHolder(null);
9152                    // don't give caller the provider object, it needs
9153                    // to make its own.
9154                    holder.provider = null;
9155                    return holder;
9156                }
9157
9158                final long origId = Binder.clearCallingIdentity();
9159
9160                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9161
9162                // In this case the provider instance already exists, so we can
9163                // return it right away.
9164                conn = incProviderCountLocked(r, cpr, token, stable);
9165                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9166                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9167                        // If this is a perceptible app accessing the provider,
9168                        // make sure to count it as being accessed and thus
9169                        // back up on the LRU list.  This is good because
9170                        // content providers are often expensive to start.
9171                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9172                        updateLruProcessLocked(cpr.proc, false, null);
9173                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9174                    }
9175                }
9176
9177                if (cpr.proc != null) {
9178                    if (false) {
9179                        if (cpr.name.flattenToShortString().equals(
9180                                "com.android.providers.calendar/.CalendarProvider2")) {
9181                            Slog.v(TAG, "****************** KILLING "
9182                                + cpr.name.flattenToShortString());
9183                            Process.killProcess(cpr.proc.pid);
9184                        }
9185                    }
9186                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9187                    boolean success = updateOomAdjLocked(cpr.proc);
9188                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9189                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9190                    // NOTE: there is still a race here where a signal could be
9191                    // pending on the process even though we managed to update its
9192                    // adj level.  Not sure what to do about this, but at least
9193                    // the race is now smaller.
9194                    if (!success) {
9195                        // Uh oh...  it looks like the provider's process
9196                        // has been killed on us.  We need to wait for a new
9197                        // process to be started, and make sure its death
9198                        // doesn't kill our process.
9199                        Slog.i(TAG,
9200                                "Existing provider " + cpr.name.flattenToShortString()
9201                                + " is crashing; detaching " + r);
9202                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9203                        checkTime(startTime, "getContentProviderImpl: before appDied");
9204                        appDiedLocked(cpr.proc);
9205                        checkTime(startTime, "getContentProviderImpl: after appDied");
9206                        if (!lastRef) {
9207                            // This wasn't the last ref our process had on
9208                            // the provider...  we have now been killed, bail.
9209                            return null;
9210                        }
9211                        providerRunning = false;
9212                        conn = null;
9213                    }
9214                }
9215
9216                Binder.restoreCallingIdentity(origId);
9217            }
9218
9219            boolean singleton;
9220            if (!providerRunning) {
9221                try {
9222                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9223                    cpi = AppGlobals.getPackageManager().
9224                        resolveContentProvider(name,
9225                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9226                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9227                } catch (RemoteException ex) {
9228                }
9229                if (cpi == null) {
9230                    return null;
9231                }
9232                // If the provider is a singleton AND
9233                // (it's a call within the same user || the provider is a
9234                // privileged app)
9235                // Then allow connecting to the singleton provider
9236                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9237                        cpi.name, cpi.flags)
9238                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9239                if (singleton) {
9240                    userId = UserHandle.USER_OWNER;
9241                }
9242                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9243                checkTime(startTime, "getContentProviderImpl: got app info for user");
9244
9245                String msg;
9246                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9247                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9248                        != null) {
9249                    throw new SecurityException(msg);
9250                }
9251                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9252
9253                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9254                        && !cpi.processName.equals("system")) {
9255                    // If this content provider does not run in the system
9256                    // process, and the system is not yet ready to run other
9257                    // processes, then fail fast instead of hanging.
9258                    throw new IllegalArgumentException(
9259                            "Attempt to launch content provider before system ready");
9260                }
9261
9262                // Make sure that the user who owns this provider is started.  If not,
9263                // we don't want to allow it to run.
9264                if (mStartedUsers.get(userId) == null) {
9265                    Slog.w(TAG, "Unable to launch app "
9266                            + cpi.applicationInfo.packageName + "/"
9267                            + cpi.applicationInfo.uid + " for provider "
9268                            + name + ": user " + userId + " is stopped");
9269                    return null;
9270                }
9271
9272                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9273                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9274                cpr = mProviderMap.getProviderByClass(comp, userId);
9275                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9276                final boolean firstClass = cpr == null;
9277                if (firstClass) {
9278                    final long ident = Binder.clearCallingIdentity();
9279                    try {
9280                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9281                        ApplicationInfo ai =
9282                            AppGlobals.getPackageManager().
9283                                getApplicationInfo(
9284                                        cpi.applicationInfo.packageName,
9285                                        STOCK_PM_FLAGS, userId);
9286                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9287                        if (ai == null) {
9288                            Slog.w(TAG, "No package info for content provider "
9289                                    + cpi.name);
9290                            return null;
9291                        }
9292                        ai = getAppInfoForUser(ai, userId);
9293                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9294                    } catch (RemoteException ex) {
9295                        // pm is in same process, this will never happen.
9296                    } finally {
9297                        Binder.restoreCallingIdentity(ident);
9298                    }
9299                }
9300
9301                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9302
9303                if (r != null && cpr.canRunHere(r)) {
9304                    // If this is a multiprocess provider, then just return its
9305                    // info and allow the caller to instantiate it.  Only do
9306                    // this if the provider is the same user as the caller's
9307                    // process, or can run as root (so can be in any process).
9308                    return cpr.newHolder(null);
9309                }
9310
9311                if (DEBUG_PROVIDER) {
9312                    RuntimeException e = new RuntimeException("here");
9313                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9314                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9315                }
9316
9317                // This is single process, and our app is now connecting to it.
9318                // See if we are already in the process of launching this
9319                // provider.
9320                final int N = mLaunchingProviders.size();
9321                int i;
9322                for (i=0; i<N; i++) {
9323                    if (mLaunchingProviders.get(i) == cpr) {
9324                        break;
9325                    }
9326                }
9327
9328                // If the provider is not already being launched, then get it
9329                // started.
9330                if (i >= N) {
9331                    final long origId = Binder.clearCallingIdentity();
9332
9333                    try {
9334                        // Content provider is now in use, its package can't be stopped.
9335                        try {
9336                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9337                            AppGlobals.getPackageManager().setPackageStoppedState(
9338                                    cpr.appInfo.packageName, false, userId);
9339                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9340                        } catch (RemoteException e) {
9341                        } catch (IllegalArgumentException e) {
9342                            Slog.w(TAG, "Failed trying to unstop package "
9343                                    + cpr.appInfo.packageName + ": " + e);
9344                        }
9345
9346                        // Use existing process if already started
9347                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9348                        ProcessRecord proc = getProcessRecordLocked(
9349                                cpi.processName, cpr.appInfo.uid, false);
9350                        if (proc != null && proc.thread != null) {
9351                            if (DEBUG_PROVIDER) {
9352                                Slog.d(TAG, "Installing in existing process " + proc);
9353                            }
9354                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9355                            proc.pubProviders.put(cpi.name, cpr);
9356                            try {
9357                                proc.thread.scheduleInstallProvider(cpi);
9358                            } catch (RemoteException e) {
9359                            }
9360                        } else {
9361                            checkTime(startTime, "getContentProviderImpl: before start process");
9362                            proc = startProcessLocked(cpi.processName,
9363                                    cpr.appInfo, false, 0, "content provider",
9364                                    new ComponentName(cpi.applicationInfo.packageName,
9365                                            cpi.name), false, false, false);
9366                            checkTime(startTime, "getContentProviderImpl: after start process");
9367                            if (proc == null) {
9368                                Slog.w(TAG, "Unable to launch app "
9369                                        + cpi.applicationInfo.packageName + "/"
9370                                        + cpi.applicationInfo.uid + " for provider "
9371                                        + name + ": process is bad");
9372                                return null;
9373                            }
9374                        }
9375                        cpr.launchingApp = proc;
9376                        mLaunchingProviders.add(cpr);
9377                    } finally {
9378                        Binder.restoreCallingIdentity(origId);
9379                    }
9380                }
9381
9382                checkTime(startTime, "getContentProviderImpl: updating data structures");
9383
9384                // Make sure the provider is published (the same provider class
9385                // may be published under multiple names).
9386                if (firstClass) {
9387                    mProviderMap.putProviderByClass(comp, cpr);
9388                }
9389
9390                mProviderMap.putProviderByName(name, cpr);
9391                conn = incProviderCountLocked(r, cpr, token, stable);
9392                if (conn != null) {
9393                    conn.waiting = true;
9394                }
9395            }
9396            checkTime(startTime, "getContentProviderImpl: done!");
9397        }
9398
9399        // Wait for the provider to be published...
9400        synchronized (cpr) {
9401            while (cpr.provider == null) {
9402                if (cpr.launchingApp == null) {
9403                    Slog.w(TAG, "Unable to launch app "
9404                            + cpi.applicationInfo.packageName + "/"
9405                            + cpi.applicationInfo.uid + " for provider "
9406                            + name + ": launching app became null");
9407                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9408                            UserHandle.getUserId(cpi.applicationInfo.uid),
9409                            cpi.applicationInfo.packageName,
9410                            cpi.applicationInfo.uid, name);
9411                    return null;
9412                }
9413                try {
9414                    if (DEBUG_MU) {
9415                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9416                                + cpr.launchingApp);
9417                    }
9418                    if (conn != null) {
9419                        conn.waiting = true;
9420                    }
9421                    cpr.wait();
9422                } catch (InterruptedException ex) {
9423                } finally {
9424                    if (conn != null) {
9425                        conn.waiting = false;
9426                    }
9427                }
9428            }
9429        }
9430        return cpr != null ? cpr.newHolder(conn) : null;
9431    }
9432
9433    @Override
9434    public final ContentProviderHolder getContentProvider(
9435            IApplicationThread caller, String name, int userId, boolean stable) {
9436        enforceNotIsolatedCaller("getContentProvider");
9437        if (caller == null) {
9438            String msg = "null IApplicationThread when getting content provider "
9439                    + name;
9440            Slog.w(TAG, msg);
9441            throw new SecurityException(msg);
9442        }
9443        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9444        // with cross-user grant.
9445        return getContentProviderImpl(caller, name, null, stable, userId);
9446    }
9447
9448    public ContentProviderHolder getContentProviderExternal(
9449            String name, int userId, IBinder token) {
9450        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9451            "Do not have permission in call getContentProviderExternal()");
9452        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9453                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9454        return getContentProviderExternalUnchecked(name, token, userId);
9455    }
9456
9457    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9458            IBinder token, int userId) {
9459        return getContentProviderImpl(null, name, token, true, userId);
9460    }
9461
9462    /**
9463     * Drop a content provider from a ProcessRecord's bookkeeping
9464     */
9465    public void removeContentProvider(IBinder connection, boolean stable) {
9466        enforceNotIsolatedCaller("removeContentProvider");
9467        long ident = Binder.clearCallingIdentity();
9468        try {
9469            synchronized (this) {
9470                ContentProviderConnection conn;
9471                try {
9472                    conn = (ContentProviderConnection)connection;
9473                } catch (ClassCastException e) {
9474                    String msg ="removeContentProvider: " + connection
9475                            + " not a ContentProviderConnection";
9476                    Slog.w(TAG, msg);
9477                    throw new IllegalArgumentException(msg);
9478                }
9479                if (conn == null) {
9480                    throw new NullPointerException("connection is null");
9481                }
9482                if (decProviderCountLocked(conn, null, null, stable)) {
9483                    updateOomAdjLocked();
9484                }
9485            }
9486        } finally {
9487            Binder.restoreCallingIdentity(ident);
9488        }
9489    }
9490
9491    public void removeContentProviderExternal(String name, IBinder token) {
9492        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9493            "Do not have permission in call removeContentProviderExternal()");
9494        int userId = UserHandle.getCallingUserId();
9495        long ident = Binder.clearCallingIdentity();
9496        try {
9497            removeContentProviderExternalUnchecked(name, token, userId);
9498        } finally {
9499            Binder.restoreCallingIdentity(ident);
9500        }
9501    }
9502
9503    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9504        synchronized (this) {
9505            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9506            if(cpr == null) {
9507                //remove from mProvidersByClass
9508                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9509                return;
9510            }
9511
9512            //update content provider record entry info
9513            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9514            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9515            if (localCpr.hasExternalProcessHandles()) {
9516                if (localCpr.removeExternalProcessHandleLocked(token)) {
9517                    updateOomAdjLocked();
9518                } else {
9519                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9520                            + " with no external reference for token: "
9521                            + token + ".");
9522                }
9523            } else {
9524                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9525                        + " with no external references.");
9526            }
9527        }
9528    }
9529
9530    public final void publishContentProviders(IApplicationThread caller,
9531            List<ContentProviderHolder> providers) {
9532        if (providers == null) {
9533            return;
9534        }
9535
9536        enforceNotIsolatedCaller("publishContentProviders");
9537        synchronized (this) {
9538            final ProcessRecord r = getRecordForAppLocked(caller);
9539            if (DEBUG_MU)
9540                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9541            if (r == null) {
9542                throw new SecurityException(
9543                        "Unable to find app for caller " + caller
9544                      + " (pid=" + Binder.getCallingPid()
9545                      + ") when publishing content providers");
9546            }
9547
9548            final long origId = Binder.clearCallingIdentity();
9549
9550            final int N = providers.size();
9551            for (int i=0; i<N; i++) {
9552                ContentProviderHolder src = providers.get(i);
9553                if (src == null || src.info == null || src.provider == null) {
9554                    continue;
9555                }
9556                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9557                if (DEBUG_MU)
9558                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9559                if (dst != null) {
9560                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9561                    mProviderMap.putProviderByClass(comp, dst);
9562                    String names[] = dst.info.authority.split(";");
9563                    for (int j = 0; j < names.length; j++) {
9564                        mProviderMap.putProviderByName(names[j], dst);
9565                    }
9566
9567                    int NL = mLaunchingProviders.size();
9568                    int j;
9569                    for (j=0; j<NL; j++) {
9570                        if (mLaunchingProviders.get(j) == dst) {
9571                            mLaunchingProviders.remove(j);
9572                            j--;
9573                            NL--;
9574                        }
9575                    }
9576                    synchronized (dst) {
9577                        dst.provider = src.provider;
9578                        dst.proc = r;
9579                        dst.notifyAll();
9580                    }
9581                    updateOomAdjLocked(r);
9582                }
9583            }
9584
9585            Binder.restoreCallingIdentity(origId);
9586        }
9587    }
9588
9589    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9590        ContentProviderConnection conn;
9591        try {
9592            conn = (ContentProviderConnection)connection;
9593        } catch (ClassCastException e) {
9594            String msg ="refContentProvider: " + connection
9595                    + " not a ContentProviderConnection";
9596            Slog.w(TAG, msg);
9597            throw new IllegalArgumentException(msg);
9598        }
9599        if (conn == null) {
9600            throw new NullPointerException("connection is null");
9601        }
9602
9603        synchronized (this) {
9604            if (stable > 0) {
9605                conn.numStableIncs += stable;
9606            }
9607            stable = conn.stableCount + stable;
9608            if (stable < 0) {
9609                throw new IllegalStateException("stableCount < 0: " + stable);
9610            }
9611
9612            if (unstable > 0) {
9613                conn.numUnstableIncs += unstable;
9614            }
9615            unstable = conn.unstableCount + unstable;
9616            if (unstable < 0) {
9617                throw new IllegalStateException("unstableCount < 0: " + unstable);
9618            }
9619
9620            if ((stable+unstable) <= 0) {
9621                throw new IllegalStateException("ref counts can't go to zero here: stable="
9622                        + stable + " unstable=" + unstable);
9623            }
9624            conn.stableCount = stable;
9625            conn.unstableCount = unstable;
9626            return !conn.dead;
9627        }
9628    }
9629
9630    public void unstableProviderDied(IBinder connection) {
9631        ContentProviderConnection conn;
9632        try {
9633            conn = (ContentProviderConnection)connection;
9634        } catch (ClassCastException e) {
9635            String msg ="refContentProvider: " + connection
9636                    + " not a ContentProviderConnection";
9637            Slog.w(TAG, msg);
9638            throw new IllegalArgumentException(msg);
9639        }
9640        if (conn == null) {
9641            throw new NullPointerException("connection is null");
9642        }
9643
9644        // Safely retrieve the content provider associated with the connection.
9645        IContentProvider provider;
9646        synchronized (this) {
9647            provider = conn.provider.provider;
9648        }
9649
9650        if (provider == null) {
9651            // Um, yeah, we're way ahead of you.
9652            return;
9653        }
9654
9655        // Make sure the caller is being honest with us.
9656        if (provider.asBinder().pingBinder()) {
9657            // Er, no, still looks good to us.
9658            synchronized (this) {
9659                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9660                        + " says " + conn + " died, but we don't agree");
9661                return;
9662            }
9663        }
9664
9665        // Well look at that!  It's dead!
9666        synchronized (this) {
9667            if (conn.provider.provider != provider) {
9668                // But something changed...  good enough.
9669                return;
9670            }
9671
9672            ProcessRecord proc = conn.provider.proc;
9673            if (proc == null || proc.thread == null) {
9674                // Seems like the process is already cleaned up.
9675                return;
9676            }
9677
9678            // As far as we're concerned, this is just like receiving a
9679            // death notification...  just a bit prematurely.
9680            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9681                    + ") early provider death");
9682            final long ident = Binder.clearCallingIdentity();
9683            try {
9684                appDiedLocked(proc);
9685            } finally {
9686                Binder.restoreCallingIdentity(ident);
9687            }
9688        }
9689    }
9690
9691    @Override
9692    public void appNotRespondingViaProvider(IBinder connection) {
9693        enforceCallingPermission(
9694                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9695
9696        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9697        if (conn == null) {
9698            Slog.w(TAG, "ContentProviderConnection is null");
9699            return;
9700        }
9701
9702        final ProcessRecord host = conn.provider.proc;
9703        if (host == null) {
9704            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9705            return;
9706        }
9707
9708        final long token = Binder.clearCallingIdentity();
9709        try {
9710            appNotResponding(host, null, null, false, "ContentProvider not responding");
9711        } finally {
9712            Binder.restoreCallingIdentity(token);
9713        }
9714    }
9715
9716    public final void installSystemProviders() {
9717        List<ProviderInfo> providers;
9718        synchronized (this) {
9719            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9720            providers = generateApplicationProvidersLocked(app);
9721            if (providers != null) {
9722                for (int i=providers.size()-1; i>=0; i--) {
9723                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9724                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9725                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9726                                + ": not system .apk");
9727                        providers.remove(i);
9728                    }
9729                }
9730            }
9731        }
9732        if (providers != null) {
9733            mSystemThread.installSystemProviders(providers);
9734        }
9735
9736        mCoreSettingsObserver = new CoreSettingsObserver(this);
9737
9738        //mUsageStatsService.monitorPackages();
9739    }
9740
9741    /**
9742     * Allows apps to retrieve the MIME type of a URI.
9743     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9744     * users, then it does not need permission to access the ContentProvider.
9745     * Either, it needs cross-user uri grants.
9746     *
9747     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9748     *
9749     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9750     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9751     */
9752    public String getProviderMimeType(Uri uri, int userId) {
9753        enforceNotIsolatedCaller("getProviderMimeType");
9754        final String name = uri.getAuthority();
9755        int callingUid = Binder.getCallingUid();
9756        int callingPid = Binder.getCallingPid();
9757        long ident = 0;
9758        boolean clearedIdentity = false;
9759        userId = unsafeConvertIncomingUser(userId);
9760        if (canClearIdentity(callingPid, callingUid, userId)) {
9761            clearedIdentity = true;
9762            ident = Binder.clearCallingIdentity();
9763        }
9764        ContentProviderHolder holder = null;
9765        try {
9766            holder = getContentProviderExternalUnchecked(name, null, userId);
9767            if (holder != null) {
9768                return holder.provider.getType(uri);
9769            }
9770        } catch (RemoteException e) {
9771            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9772            return null;
9773        } finally {
9774            // We need to clear the identity to call removeContentProviderExternalUnchecked
9775            if (!clearedIdentity) {
9776                ident = Binder.clearCallingIdentity();
9777            }
9778            try {
9779                if (holder != null) {
9780                    removeContentProviderExternalUnchecked(name, null, userId);
9781                }
9782            } finally {
9783                Binder.restoreCallingIdentity(ident);
9784            }
9785        }
9786
9787        return null;
9788    }
9789
9790    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9791        if (UserHandle.getUserId(callingUid) == userId) {
9792            return true;
9793        }
9794        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9795                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9796                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9797                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9798                return true;
9799        }
9800        return false;
9801    }
9802
9803    // =========================================================
9804    // GLOBAL MANAGEMENT
9805    // =========================================================
9806
9807    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9808            boolean isolated, int isolatedUid) {
9809        String proc = customProcess != null ? customProcess : info.processName;
9810        BatteryStatsImpl.Uid.Proc ps = null;
9811        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9812        int uid = info.uid;
9813        if (isolated) {
9814            if (isolatedUid == 0) {
9815                int userId = UserHandle.getUserId(uid);
9816                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9817                while (true) {
9818                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9819                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9820                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9821                    }
9822                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9823                    mNextIsolatedProcessUid++;
9824                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9825                        // No process for this uid, use it.
9826                        break;
9827                    }
9828                    stepsLeft--;
9829                    if (stepsLeft <= 0) {
9830                        return null;
9831                    }
9832                }
9833            } else {
9834                // Special case for startIsolatedProcess (internal only), where
9835                // the uid of the isolated process is specified by the caller.
9836                uid = isolatedUid;
9837            }
9838        }
9839        return new ProcessRecord(stats, info, proc, uid);
9840    }
9841
9842    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9843            String abiOverride) {
9844        ProcessRecord app;
9845        if (!isolated) {
9846            app = getProcessRecordLocked(info.processName, info.uid, true);
9847        } else {
9848            app = null;
9849        }
9850
9851        if (app == null) {
9852            app = newProcessRecordLocked(info, null, isolated, 0);
9853            mProcessNames.put(info.processName, app.uid, app);
9854            if (isolated) {
9855                mIsolatedProcesses.put(app.uid, app);
9856            }
9857            updateLruProcessLocked(app, false, null);
9858            updateOomAdjLocked();
9859        }
9860
9861        // This package really, really can not be stopped.
9862        try {
9863            AppGlobals.getPackageManager().setPackageStoppedState(
9864                    info.packageName, false, UserHandle.getUserId(app.uid));
9865        } catch (RemoteException e) {
9866        } catch (IllegalArgumentException e) {
9867            Slog.w(TAG, "Failed trying to unstop package "
9868                    + info.packageName + ": " + e);
9869        }
9870
9871        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9872                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9873            app.persistent = true;
9874            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9875        }
9876        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9877            mPersistentStartingProcesses.add(app);
9878            startProcessLocked(app, "added application", app.processName, abiOverride,
9879                    null /* entryPoint */, null /* entryPointArgs */);
9880        }
9881
9882        return app;
9883    }
9884
9885    public void unhandledBack() {
9886        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9887                "unhandledBack()");
9888
9889        synchronized(this) {
9890            final long origId = Binder.clearCallingIdentity();
9891            try {
9892                getFocusedStack().unhandledBackLocked();
9893            } finally {
9894                Binder.restoreCallingIdentity(origId);
9895            }
9896        }
9897    }
9898
9899    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9900        enforceNotIsolatedCaller("openContentUri");
9901        final int userId = UserHandle.getCallingUserId();
9902        String name = uri.getAuthority();
9903        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9904        ParcelFileDescriptor pfd = null;
9905        if (cph != null) {
9906            // We record the binder invoker's uid in thread-local storage before
9907            // going to the content provider to open the file.  Later, in the code
9908            // that handles all permissions checks, we look for this uid and use
9909            // that rather than the Activity Manager's own uid.  The effect is that
9910            // we do the check against the caller's permissions even though it looks
9911            // to the content provider like the Activity Manager itself is making
9912            // the request.
9913            sCallerIdentity.set(new Identity(
9914                    Binder.getCallingPid(), Binder.getCallingUid()));
9915            try {
9916                pfd = cph.provider.openFile(null, uri, "r", null);
9917            } catch (FileNotFoundException e) {
9918                // do nothing; pfd will be returned null
9919            } finally {
9920                // Ensure that whatever happens, we clean up the identity state
9921                sCallerIdentity.remove();
9922            }
9923
9924            // We've got the fd now, so we're done with the provider.
9925            removeContentProviderExternalUnchecked(name, null, userId);
9926        } else {
9927            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9928        }
9929        return pfd;
9930    }
9931
9932    // Actually is sleeping or shutting down or whatever else in the future
9933    // is an inactive state.
9934    public boolean isSleepingOrShuttingDown() {
9935        return isSleeping() || mShuttingDown;
9936    }
9937
9938    public boolean isSleeping() {
9939        return mSleeping;
9940    }
9941
9942    void goingToSleep() {
9943        synchronized(this) {
9944            mWentToSleep = true;
9945            goToSleepIfNeededLocked();
9946        }
9947    }
9948
9949    void finishRunningVoiceLocked() {
9950        if (mRunningVoice) {
9951            mRunningVoice = false;
9952            goToSleepIfNeededLocked();
9953        }
9954    }
9955
9956    void goToSleepIfNeededLocked() {
9957        if (mWentToSleep && !mRunningVoice) {
9958            if (!mSleeping) {
9959                mSleeping = true;
9960                mStackSupervisor.goingToSleepLocked();
9961
9962                // Initialize the wake times of all processes.
9963                checkExcessivePowerUsageLocked(false);
9964                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9965                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9966                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9967            }
9968        }
9969    }
9970
9971    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9972        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9973            // Never persist the home stack.
9974            return;
9975        }
9976        mTaskPersister.wakeup(task, flush);
9977    }
9978
9979    @Override
9980    public boolean shutdown(int timeout) {
9981        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9982                != PackageManager.PERMISSION_GRANTED) {
9983            throw new SecurityException("Requires permission "
9984                    + android.Manifest.permission.SHUTDOWN);
9985        }
9986
9987        boolean timedout = false;
9988
9989        synchronized(this) {
9990            mShuttingDown = true;
9991            updateEventDispatchingLocked();
9992            timedout = mStackSupervisor.shutdownLocked(timeout);
9993        }
9994
9995        mAppOpsService.shutdown();
9996        if (mUsageStatsService != null) {
9997            mUsageStatsService.prepareShutdown();
9998        }
9999        mBatteryStatsService.shutdown();
10000        synchronized (this) {
10001            mProcessStats.shutdownLocked();
10002        }
10003        notifyTaskPersisterLocked(null, true);
10004
10005        return timedout;
10006    }
10007
10008    public final void activitySlept(IBinder token) {
10009        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10010
10011        final long origId = Binder.clearCallingIdentity();
10012
10013        synchronized (this) {
10014            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10015            if (r != null) {
10016                mStackSupervisor.activitySleptLocked(r);
10017            }
10018        }
10019
10020        Binder.restoreCallingIdentity(origId);
10021    }
10022
10023    private String lockScreenShownToString() {
10024        switch (mLockScreenShown) {
10025            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10026            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10027            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10028            default: return "Unknown=" + mLockScreenShown;
10029        }
10030    }
10031
10032    void logLockScreen(String msg) {
10033        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10034                " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" +
10035                mWentToSleep + " mSleeping=" + mSleeping);
10036    }
10037
10038    void comeOutOfSleepIfNeededLocked() {
10039        if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) {
10040            if (mSleeping) {
10041                mSleeping = false;
10042                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10043            }
10044        }
10045    }
10046
10047    void wakingUp() {
10048        synchronized(this) {
10049            mWentToSleep = false;
10050            comeOutOfSleepIfNeededLocked();
10051        }
10052    }
10053
10054    void startRunningVoiceLocked() {
10055        if (!mRunningVoice) {
10056            mRunningVoice = true;
10057            comeOutOfSleepIfNeededLocked();
10058        }
10059    }
10060
10061    private void updateEventDispatchingLocked() {
10062        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10063    }
10064
10065    public void setLockScreenShown(boolean shown) {
10066        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10067                != PackageManager.PERMISSION_GRANTED) {
10068            throw new SecurityException("Requires permission "
10069                    + android.Manifest.permission.DEVICE_POWER);
10070        }
10071
10072        synchronized(this) {
10073            long ident = Binder.clearCallingIdentity();
10074            try {
10075                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10076                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10077                comeOutOfSleepIfNeededLocked();
10078            } finally {
10079                Binder.restoreCallingIdentity(ident);
10080            }
10081        }
10082    }
10083
10084    @Override
10085    public void stopAppSwitches() {
10086        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10087                != PackageManager.PERMISSION_GRANTED) {
10088            throw new SecurityException("Requires permission "
10089                    + android.Manifest.permission.STOP_APP_SWITCHES);
10090        }
10091
10092        synchronized(this) {
10093            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10094                    + APP_SWITCH_DELAY_TIME;
10095            mDidAppSwitch = false;
10096            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10097            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10098            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10099        }
10100    }
10101
10102    public void resumeAppSwitches() {
10103        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10104                != PackageManager.PERMISSION_GRANTED) {
10105            throw new SecurityException("Requires permission "
10106                    + android.Manifest.permission.STOP_APP_SWITCHES);
10107        }
10108
10109        synchronized(this) {
10110            // Note that we don't execute any pending app switches... we will
10111            // let those wait until either the timeout, or the next start
10112            // activity request.
10113            mAppSwitchesAllowedTime = 0;
10114        }
10115    }
10116
10117    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10118            int callingPid, int callingUid, String name) {
10119        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10120            return true;
10121        }
10122
10123        int perm = checkComponentPermission(
10124                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10125                sourceUid, -1, true);
10126        if (perm == PackageManager.PERMISSION_GRANTED) {
10127            return true;
10128        }
10129
10130        // If the actual IPC caller is different from the logical source, then
10131        // also see if they are allowed to control app switches.
10132        if (callingUid != -1 && callingUid != sourceUid) {
10133            perm = checkComponentPermission(
10134                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10135                    callingUid, -1, true);
10136            if (perm == PackageManager.PERMISSION_GRANTED) {
10137                return true;
10138            }
10139        }
10140
10141        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10142        return false;
10143    }
10144
10145    public void setDebugApp(String packageName, boolean waitForDebugger,
10146            boolean persistent) {
10147        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10148                "setDebugApp()");
10149
10150        long ident = Binder.clearCallingIdentity();
10151        try {
10152            // Note that this is not really thread safe if there are multiple
10153            // callers into it at the same time, but that's not a situation we
10154            // care about.
10155            if (persistent) {
10156                final ContentResolver resolver = mContext.getContentResolver();
10157                Settings.Global.putString(
10158                    resolver, Settings.Global.DEBUG_APP,
10159                    packageName);
10160                Settings.Global.putInt(
10161                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10162                    waitForDebugger ? 1 : 0);
10163            }
10164
10165            synchronized (this) {
10166                if (!persistent) {
10167                    mOrigDebugApp = mDebugApp;
10168                    mOrigWaitForDebugger = mWaitForDebugger;
10169                }
10170                mDebugApp = packageName;
10171                mWaitForDebugger = waitForDebugger;
10172                mDebugTransient = !persistent;
10173                if (packageName != null) {
10174                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10175                            false, UserHandle.USER_ALL, "set debug app");
10176                }
10177            }
10178        } finally {
10179            Binder.restoreCallingIdentity(ident);
10180        }
10181    }
10182
10183    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10184        synchronized (this) {
10185            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10186            if (!isDebuggable) {
10187                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10188                    throw new SecurityException("Process not debuggable: " + app.packageName);
10189                }
10190            }
10191
10192            mOpenGlTraceApp = processName;
10193        }
10194    }
10195
10196    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10197        synchronized (this) {
10198            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10199            if (!isDebuggable) {
10200                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10201                    throw new SecurityException("Process not debuggable: " + app.packageName);
10202                }
10203            }
10204            mProfileApp = processName;
10205            mProfileFile = profilerInfo.profileFile;
10206            if (mProfileFd != null) {
10207                try {
10208                    mProfileFd.close();
10209                } catch (IOException e) {
10210                }
10211                mProfileFd = null;
10212            }
10213            mProfileFd = profilerInfo.profileFd;
10214            mSamplingInterval = profilerInfo.samplingInterval;
10215            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10216            mProfileType = 0;
10217        }
10218    }
10219
10220    @Override
10221    public void setAlwaysFinish(boolean enabled) {
10222        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10223                "setAlwaysFinish()");
10224
10225        Settings.Global.putInt(
10226                mContext.getContentResolver(),
10227                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10228
10229        synchronized (this) {
10230            mAlwaysFinishActivities = enabled;
10231        }
10232    }
10233
10234    @Override
10235    public void setActivityController(IActivityController controller) {
10236        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10237                "setActivityController()");
10238        synchronized (this) {
10239            mController = controller;
10240            Watchdog.getInstance().setActivityController(controller);
10241        }
10242    }
10243
10244    @Override
10245    public void setUserIsMonkey(boolean userIsMonkey) {
10246        synchronized (this) {
10247            synchronized (mPidsSelfLocked) {
10248                final int callingPid = Binder.getCallingPid();
10249                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10250                if (precessRecord == null) {
10251                    throw new SecurityException("Unknown process: " + callingPid);
10252                }
10253                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10254                    throw new SecurityException("Only an instrumentation process "
10255                            + "with a UiAutomation can call setUserIsMonkey");
10256                }
10257            }
10258            mUserIsMonkey = userIsMonkey;
10259        }
10260    }
10261
10262    @Override
10263    public boolean isUserAMonkey() {
10264        synchronized (this) {
10265            // If there is a controller also implies the user is a monkey.
10266            return (mUserIsMonkey || mController != null);
10267        }
10268    }
10269
10270    public void requestBugReport() {
10271        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10272        SystemProperties.set("ctl.start", "bugreport");
10273    }
10274
10275    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10276        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10277    }
10278
10279    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10280        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10281            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10282        }
10283        return KEY_DISPATCHING_TIMEOUT;
10284    }
10285
10286    @Override
10287    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10288        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10289                != PackageManager.PERMISSION_GRANTED) {
10290            throw new SecurityException("Requires permission "
10291                    + android.Manifest.permission.FILTER_EVENTS);
10292        }
10293        ProcessRecord proc;
10294        long timeout;
10295        synchronized (this) {
10296            synchronized (mPidsSelfLocked) {
10297                proc = mPidsSelfLocked.get(pid);
10298            }
10299            timeout = getInputDispatchingTimeoutLocked(proc);
10300        }
10301
10302        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10303            return -1;
10304        }
10305
10306        return timeout;
10307    }
10308
10309    /**
10310     * Handle input dispatching timeouts.
10311     * Returns whether input dispatching should be aborted or not.
10312     */
10313    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10314            final ActivityRecord activity, final ActivityRecord parent,
10315            final boolean aboveSystem, String reason) {
10316        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10317                != PackageManager.PERMISSION_GRANTED) {
10318            throw new SecurityException("Requires permission "
10319                    + android.Manifest.permission.FILTER_EVENTS);
10320        }
10321
10322        final String annotation;
10323        if (reason == null) {
10324            annotation = "Input dispatching timed out";
10325        } else {
10326            annotation = "Input dispatching timed out (" + reason + ")";
10327        }
10328
10329        if (proc != null) {
10330            synchronized (this) {
10331                if (proc.debugging) {
10332                    return false;
10333                }
10334
10335                if (mDidDexOpt) {
10336                    // Give more time since we were dexopting.
10337                    mDidDexOpt = false;
10338                    return false;
10339                }
10340
10341                if (proc.instrumentationClass != null) {
10342                    Bundle info = new Bundle();
10343                    info.putString("shortMsg", "keyDispatchingTimedOut");
10344                    info.putString("longMsg", annotation);
10345                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10346                    return true;
10347                }
10348            }
10349            mHandler.post(new Runnable() {
10350                @Override
10351                public void run() {
10352                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10353                }
10354            });
10355        }
10356
10357        return true;
10358    }
10359
10360    public Bundle getAssistContextExtras(int requestType) {
10361        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10362                UserHandle.getCallingUserId());
10363        if (pae == null) {
10364            return null;
10365        }
10366        synchronized (pae) {
10367            while (!pae.haveResult) {
10368                try {
10369                    pae.wait();
10370                } catch (InterruptedException e) {
10371                }
10372            }
10373            if (pae.result != null) {
10374                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10375            }
10376        }
10377        synchronized (this) {
10378            mPendingAssistExtras.remove(pae);
10379            mHandler.removeCallbacks(pae);
10380        }
10381        return pae.extras;
10382    }
10383
10384    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10385            int userHandle) {
10386        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10387                "getAssistContextExtras()");
10388        PendingAssistExtras pae;
10389        Bundle extras = new Bundle();
10390        synchronized (this) {
10391            ActivityRecord activity = getFocusedStack().mResumedActivity;
10392            if (activity == null) {
10393                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10394                return null;
10395            }
10396            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10397            if (activity.app == null || activity.app.thread == null) {
10398                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10399                return null;
10400            }
10401            if (activity.app.pid == Binder.getCallingPid()) {
10402                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10403                return null;
10404            }
10405            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10406            try {
10407                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10408                        requestType);
10409                mPendingAssistExtras.add(pae);
10410                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10411            } catch (RemoteException e) {
10412                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10413                return null;
10414            }
10415            return pae;
10416        }
10417    }
10418
10419    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10420        PendingAssistExtras pae = (PendingAssistExtras)token;
10421        synchronized (pae) {
10422            pae.result = extras;
10423            pae.haveResult = true;
10424            pae.notifyAll();
10425            if (pae.intent == null) {
10426                // Caller is just waiting for the result.
10427                return;
10428            }
10429        }
10430
10431        // We are now ready to launch the assist activity.
10432        synchronized (this) {
10433            boolean exists = mPendingAssistExtras.remove(pae);
10434            mHandler.removeCallbacks(pae);
10435            if (!exists) {
10436                // Timed out.
10437                return;
10438            }
10439        }
10440        pae.intent.replaceExtras(extras);
10441        if (pae.hint != null) {
10442            pae.intent.putExtra(pae.hint, true);
10443        }
10444        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10445                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10446                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10447        closeSystemDialogs("assist");
10448        try {
10449            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10450        } catch (ActivityNotFoundException e) {
10451            Slog.w(TAG, "No activity to handle assist action.", e);
10452        }
10453    }
10454
10455    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10456        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10457    }
10458
10459    public void registerProcessObserver(IProcessObserver observer) {
10460        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10461                "registerProcessObserver()");
10462        synchronized (this) {
10463            mProcessObservers.register(observer);
10464        }
10465    }
10466
10467    @Override
10468    public void unregisterProcessObserver(IProcessObserver observer) {
10469        synchronized (this) {
10470            mProcessObservers.unregister(observer);
10471        }
10472    }
10473
10474    @Override
10475    public boolean convertFromTranslucent(IBinder token) {
10476        final long origId = Binder.clearCallingIdentity();
10477        try {
10478            synchronized (this) {
10479                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10480                if (r == null) {
10481                    return false;
10482                }
10483                final boolean translucentChanged = r.changeWindowTranslucency(true);
10484                if (translucentChanged) {
10485                    r.task.stack.releaseBackgroundResources();
10486                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10487                }
10488                mWindowManager.setAppFullscreen(token, true);
10489                return translucentChanged;
10490            }
10491        } finally {
10492            Binder.restoreCallingIdentity(origId);
10493        }
10494    }
10495
10496    @Override
10497    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10498        final long origId = Binder.clearCallingIdentity();
10499        try {
10500            synchronized (this) {
10501                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10502                if (r == null) {
10503                    return false;
10504                }
10505                int index = r.task.mActivities.lastIndexOf(r);
10506                if (index > 0) {
10507                    ActivityRecord under = r.task.mActivities.get(index - 1);
10508                    under.returningOptions = options;
10509                }
10510                final boolean translucentChanged = r.changeWindowTranslucency(false);
10511                if (translucentChanged) {
10512                    r.task.stack.convertToTranslucent(r);
10513                }
10514                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10515                mWindowManager.setAppFullscreen(token, false);
10516                return translucentChanged;
10517            }
10518        } finally {
10519            Binder.restoreCallingIdentity(origId);
10520        }
10521    }
10522
10523    @Override
10524    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10525        final long origId = Binder.clearCallingIdentity();
10526        try {
10527            synchronized (this) {
10528                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10529                if (r != null) {
10530                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10531                }
10532            }
10533            return false;
10534        } finally {
10535            Binder.restoreCallingIdentity(origId);
10536        }
10537    }
10538
10539    @Override
10540    public boolean isBackgroundVisibleBehind(IBinder token) {
10541        final long origId = Binder.clearCallingIdentity();
10542        try {
10543            synchronized (this) {
10544                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10545                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10546                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10547                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10548                return visible;
10549            }
10550        } finally {
10551            Binder.restoreCallingIdentity(origId);
10552        }
10553    }
10554
10555    @Override
10556    public ActivityOptions getActivityOptions(IBinder token) {
10557        final long origId = Binder.clearCallingIdentity();
10558        try {
10559            synchronized (this) {
10560                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10561                if (r != null) {
10562                    final ActivityOptions activityOptions = r.pendingOptions;
10563                    r.pendingOptions = null;
10564                    return activityOptions;
10565                }
10566                return null;
10567            }
10568        } finally {
10569            Binder.restoreCallingIdentity(origId);
10570        }
10571    }
10572
10573    @Override
10574    public void setImmersive(IBinder token, boolean immersive) {
10575        synchronized(this) {
10576            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10577            if (r == null) {
10578                throw new IllegalArgumentException();
10579            }
10580            r.immersive = immersive;
10581
10582            // update associated state if we're frontmost
10583            if (r == mFocusedActivity) {
10584                if (DEBUG_IMMERSIVE) {
10585                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10586                }
10587                applyUpdateLockStateLocked(r);
10588            }
10589        }
10590    }
10591
10592    @Override
10593    public boolean isImmersive(IBinder token) {
10594        synchronized (this) {
10595            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10596            if (r == null) {
10597                throw new IllegalArgumentException();
10598            }
10599            return r.immersive;
10600        }
10601    }
10602
10603    public boolean isTopActivityImmersive() {
10604        enforceNotIsolatedCaller("startActivity");
10605        synchronized (this) {
10606            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10607            return (r != null) ? r.immersive : false;
10608        }
10609    }
10610
10611    @Override
10612    public boolean isTopOfTask(IBinder token) {
10613        synchronized (this) {
10614            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10615            if (r == null) {
10616                throw new IllegalArgumentException();
10617            }
10618            return r.task.getTopActivity() == r;
10619        }
10620    }
10621
10622    public final void enterSafeMode() {
10623        synchronized(this) {
10624            // It only makes sense to do this before the system is ready
10625            // and started launching other packages.
10626            if (!mSystemReady) {
10627                try {
10628                    AppGlobals.getPackageManager().enterSafeMode();
10629                } catch (RemoteException e) {
10630                }
10631            }
10632
10633            mSafeMode = true;
10634        }
10635    }
10636
10637    public final void showSafeModeOverlay() {
10638        View v = LayoutInflater.from(mContext).inflate(
10639                com.android.internal.R.layout.safe_mode, null);
10640        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10641        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10642        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10643        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10644        lp.gravity = Gravity.BOTTOM | Gravity.START;
10645        lp.format = v.getBackground().getOpacity();
10646        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10647                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10648        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10649        ((WindowManager)mContext.getSystemService(
10650                Context.WINDOW_SERVICE)).addView(v, lp);
10651    }
10652
10653    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10654        if (!(sender instanceof PendingIntentRecord)) {
10655            return;
10656        }
10657        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10658        synchronized (stats) {
10659            if (mBatteryStatsService.isOnBattery()) {
10660                mBatteryStatsService.enforceCallingPermission();
10661                PendingIntentRecord rec = (PendingIntentRecord)sender;
10662                int MY_UID = Binder.getCallingUid();
10663                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10664                BatteryStatsImpl.Uid.Pkg pkg =
10665                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10666                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10667                pkg.incWakeupsLocked();
10668            }
10669        }
10670    }
10671
10672    public boolean killPids(int[] pids, String pReason, boolean secure) {
10673        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10674            throw new SecurityException("killPids only available to the system");
10675        }
10676        String reason = (pReason == null) ? "Unknown" : pReason;
10677        // XXX Note: don't acquire main activity lock here, because the window
10678        // manager calls in with its locks held.
10679
10680        boolean killed = false;
10681        synchronized (mPidsSelfLocked) {
10682            int[] types = new int[pids.length];
10683            int worstType = 0;
10684            for (int i=0; i<pids.length; i++) {
10685                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10686                if (proc != null) {
10687                    int type = proc.setAdj;
10688                    types[i] = type;
10689                    if (type > worstType) {
10690                        worstType = type;
10691                    }
10692                }
10693            }
10694
10695            // If the worst oom_adj is somewhere in the cached proc LRU range,
10696            // then constrain it so we will kill all cached procs.
10697            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10698                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10699                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10700            }
10701
10702            // If this is not a secure call, don't let it kill processes that
10703            // are important.
10704            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10705                worstType = ProcessList.SERVICE_ADJ;
10706            }
10707
10708            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10709            for (int i=0; i<pids.length; i++) {
10710                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10711                if (proc == null) {
10712                    continue;
10713                }
10714                int adj = proc.setAdj;
10715                if (adj >= worstType && !proc.killedByAm) {
10716                    proc.kill(reason, true);
10717                    killed = true;
10718                }
10719            }
10720        }
10721        return killed;
10722    }
10723
10724    @Override
10725    public void killUid(int uid, String reason) {
10726        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10727            throw new SecurityException("killUid only available to the system");
10728        }
10729        synchronized (this) {
10730            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10731                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10732                    reason != null ? reason : "kill uid");
10733        }
10734    }
10735
10736    @Override
10737    public boolean killProcessesBelowForeground(String reason) {
10738        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10739            throw new SecurityException("killProcessesBelowForeground() only available to system");
10740        }
10741
10742        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10743    }
10744
10745    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10746        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10747            throw new SecurityException("killProcessesBelowAdj() only available to system");
10748        }
10749
10750        boolean killed = false;
10751        synchronized (mPidsSelfLocked) {
10752            final int size = mPidsSelfLocked.size();
10753            for (int i = 0; i < size; i++) {
10754                final int pid = mPidsSelfLocked.keyAt(i);
10755                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10756                if (proc == null) continue;
10757
10758                final int adj = proc.setAdj;
10759                if (adj > belowAdj && !proc.killedByAm) {
10760                    proc.kill(reason, true);
10761                    killed = true;
10762                }
10763            }
10764        }
10765        return killed;
10766    }
10767
10768    @Override
10769    public void hang(final IBinder who, boolean allowRestart) {
10770        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10771                != PackageManager.PERMISSION_GRANTED) {
10772            throw new SecurityException("Requires permission "
10773                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10774        }
10775
10776        final IBinder.DeathRecipient death = new DeathRecipient() {
10777            @Override
10778            public void binderDied() {
10779                synchronized (this) {
10780                    notifyAll();
10781                }
10782            }
10783        };
10784
10785        try {
10786            who.linkToDeath(death, 0);
10787        } catch (RemoteException e) {
10788            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10789            return;
10790        }
10791
10792        synchronized (this) {
10793            Watchdog.getInstance().setAllowRestart(allowRestart);
10794            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10795            synchronized (death) {
10796                while (who.isBinderAlive()) {
10797                    try {
10798                        death.wait();
10799                    } catch (InterruptedException e) {
10800                    }
10801                }
10802            }
10803            Watchdog.getInstance().setAllowRestart(true);
10804        }
10805    }
10806
10807    @Override
10808    public void restart() {
10809        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10810                != PackageManager.PERMISSION_GRANTED) {
10811            throw new SecurityException("Requires permission "
10812                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10813        }
10814
10815        Log.i(TAG, "Sending shutdown broadcast...");
10816
10817        BroadcastReceiver br = new BroadcastReceiver() {
10818            @Override public void onReceive(Context context, Intent intent) {
10819                // Now the broadcast is done, finish up the low-level shutdown.
10820                Log.i(TAG, "Shutting down activity manager...");
10821                shutdown(10000);
10822                Log.i(TAG, "Shutdown complete, restarting!");
10823                Process.killProcess(Process.myPid());
10824                System.exit(10);
10825            }
10826        };
10827
10828        // First send the high-level shut down broadcast.
10829        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10830        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10831        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10832        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10833        mContext.sendOrderedBroadcastAsUser(intent,
10834                UserHandle.ALL, null, br, mHandler, 0, null, null);
10835        */
10836        br.onReceive(mContext, intent);
10837    }
10838
10839    private long getLowRamTimeSinceIdle(long now) {
10840        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10841    }
10842
10843    @Override
10844    public void performIdleMaintenance() {
10845        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10846                != PackageManager.PERMISSION_GRANTED) {
10847            throw new SecurityException("Requires permission "
10848                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10849        }
10850
10851        synchronized (this) {
10852            final long now = SystemClock.uptimeMillis();
10853            final long timeSinceLastIdle = now - mLastIdleTime;
10854            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10855            mLastIdleTime = now;
10856            mLowRamTimeSinceLastIdle = 0;
10857            if (mLowRamStartTime != 0) {
10858                mLowRamStartTime = now;
10859            }
10860
10861            StringBuilder sb = new StringBuilder(128);
10862            sb.append("Idle maintenance over ");
10863            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10864            sb.append(" low RAM for ");
10865            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10866            Slog.i(TAG, sb.toString());
10867
10868            // If at least 1/3 of our time since the last idle period has been spent
10869            // with RAM low, then we want to kill processes.
10870            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10871
10872            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10873                ProcessRecord proc = mLruProcesses.get(i);
10874                if (proc.notCachedSinceIdle) {
10875                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10876                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10877                        if (doKilling && proc.initialIdlePss != 0
10878                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10879                            proc.kill("idle maint (pss " + proc.lastPss
10880                                    + " from " + proc.initialIdlePss + ")", true);
10881                        }
10882                    }
10883                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10884                    proc.notCachedSinceIdle = true;
10885                    proc.initialIdlePss = 0;
10886                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10887                            isSleeping(), now);
10888                }
10889            }
10890
10891            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10892            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10893        }
10894    }
10895
10896    private void retrieveSettings() {
10897        final ContentResolver resolver = mContext.getContentResolver();
10898        String debugApp = Settings.Global.getString(
10899            resolver, Settings.Global.DEBUG_APP);
10900        boolean waitForDebugger = Settings.Global.getInt(
10901            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10902        boolean alwaysFinishActivities = Settings.Global.getInt(
10903            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10904        boolean forceRtl = Settings.Global.getInt(
10905                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10906        // Transfer any global setting for forcing RTL layout, into a System Property
10907        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10908
10909        Configuration configuration = new Configuration();
10910        Settings.System.getConfiguration(resolver, configuration);
10911        if (forceRtl) {
10912            // This will take care of setting the correct layout direction flags
10913            configuration.setLayoutDirection(configuration.locale);
10914        }
10915
10916        synchronized (this) {
10917            mDebugApp = mOrigDebugApp = debugApp;
10918            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10919            mAlwaysFinishActivities = alwaysFinishActivities;
10920            // This happens before any activities are started, so we can
10921            // change mConfiguration in-place.
10922            updateConfigurationLocked(configuration, null, false, true);
10923            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10924        }
10925    }
10926
10927    /** Loads resources after the current configuration has been set. */
10928    private void loadResourcesOnSystemReady() {
10929        final Resources res = mContext.getResources();
10930        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10931        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10932        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10933    }
10934
10935    public boolean testIsSystemReady() {
10936        // no need to synchronize(this) just to read & return the value
10937        return mSystemReady;
10938    }
10939
10940    private static File getCalledPreBootReceiversFile() {
10941        File dataDir = Environment.getDataDirectory();
10942        File systemDir = new File(dataDir, "system");
10943        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10944        return fname;
10945    }
10946
10947    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10948        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10949        File file = getCalledPreBootReceiversFile();
10950        FileInputStream fis = null;
10951        try {
10952            fis = new FileInputStream(file);
10953            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10954            int fvers = dis.readInt();
10955            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10956                String vers = dis.readUTF();
10957                String codename = dis.readUTF();
10958                String build = dis.readUTF();
10959                if (android.os.Build.VERSION.RELEASE.equals(vers)
10960                        && android.os.Build.VERSION.CODENAME.equals(codename)
10961                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10962                    int num = dis.readInt();
10963                    while (num > 0) {
10964                        num--;
10965                        String pkg = dis.readUTF();
10966                        String cls = dis.readUTF();
10967                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10968                    }
10969                }
10970            }
10971        } catch (FileNotFoundException e) {
10972        } catch (IOException e) {
10973            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10974        } finally {
10975            if (fis != null) {
10976                try {
10977                    fis.close();
10978                } catch (IOException e) {
10979                }
10980            }
10981        }
10982        return lastDoneReceivers;
10983    }
10984
10985    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10986        File file = getCalledPreBootReceiversFile();
10987        FileOutputStream fos = null;
10988        DataOutputStream dos = null;
10989        try {
10990            fos = new FileOutputStream(file);
10991            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10992            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10993            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10994            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10995            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10996            dos.writeInt(list.size());
10997            for (int i=0; i<list.size(); i++) {
10998                dos.writeUTF(list.get(i).getPackageName());
10999                dos.writeUTF(list.get(i).getClassName());
11000            }
11001        } catch (IOException e) {
11002            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11003            file.delete();
11004        } finally {
11005            FileUtils.sync(fos);
11006            if (dos != null) {
11007                try {
11008                    dos.close();
11009                } catch (IOException e) {
11010                    // TODO Auto-generated catch block
11011                    e.printStackTrace();
11012                }
11013            }
11014        }
11015    }
11016
11017    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11018            ArrayList<ComponentName> doneReceivers, int userId) {
11019        boolean waitingUpdate = false;
11020        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11021        List<ResolveInfo> ris = null;
11022        try {
11023            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11024                    intent, null, 0, userId);
11025        } catch (RemoteException e) {
11026        }
11027        if (ris != null) {
11028            for (int i=ris.size()-1; i>=0; i--) {
11029                if ((ris.get(i).activityInfo.applicationInfo.flags
11030                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11031                    ris.remove(i);
11032                }
11033            }
11034            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11035
11036            // For User 0, load the version number. When delivering to a new user, deliver
11037            // to all receivers.
11038            if (userId == UserHandle.USER_OWNER) {
11039                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11040                for (int i=0; i<ris.size(); i++) {
11041                    ActivityInfo ai = ris.get(i).activityInfo;
11042                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11043                    if (lastDoneReceivers.contains(comp)) {
11044                        // We already did the pre boot receiver for this app with the current
11045                        // platform version, so don't do it again...
11046                        ris.remove(i);
11047                        i--;
11048                        // ...however, do keep it as one that has been done, so we don't
11049                        // forget about it when rewriting the file of last done receivers.
11050                        doneReceivers.add(comp);
11051                    }
11052                }
11053            }
11054
11055            // If primary user, send broadcast to all available users, else just to userId
11056            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11057                    : new int[] { userId };
11058            for (int i = 0; i < ris.size(); i++) {
11059                ActivityInfo ai = ris.get(i).activityInfo;
11060                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11061                doneReceivers.add(comp);
11062                intent.setComponent(comp);
11063                for (int j=0; j<users.length; j++) {
11064                    IIntentReceiver finisher = null;
11065                    // On last receiver and user, set up a completion callback
11066                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11067                        finisher = new IIntentReceiver.Stub() {
11068                            public void performReceive(Intent intent, int resultCode,
11069                                    String data, Bundle extras, boolean ordered,
11070                                    boolean sticky, int sendingUser) {
11071                                // The raw IIntentReceiver interface is called
11072                                // with the AM lock held, so redispatch to
11073                                // execute our code without the lock.
11074                                mHandler.post(onFinishCallback);
11075                            }
11076                        };
11077                    }
11078                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11079                            + " for user " + users[j]);
11080                    broadcastIntentLocked(null, null, intent, null, finisher,
11081                            0, null, null, null, AppOpsManager.OP_NONE,
11082                            true, false, MY_PID, Process.SYSTEM_UID,
11083                            users[j]);
11084                    if (finisher != null) {
11085                        waitingUpdate = true;
11086                    }
11087                }
11088            }
11089        }
11090
11091        return waitingUpdate;
11092    }
11093
11094    public void systemReady(final Runnable goingCallback) {
11095        synchronized(this) {
11096            if (mSystemReady) {
11097                // If we're done calling all the receivers, run the next "boot phase" passed in
11098                // by the SystemServer
11099                if (goingCallback != null) {
11100                    goingCallback.run();
11101                }
11102                return;
11103            }
11104
11105            // Make sure we have the current profile info, since it is needed for
11106            // security checks.
11107            updateCurrentProfileIdsLocked();
11108
11109            if (mRecentTasks == null) {
11110                mRecentTasks = mTaskPersister.restoreTasksLocked();
11111                if (!mRecentTasks.isEmpty()) {
11112                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11113                }
11114                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11115                mTaskPersister.startPersisting();
11116            }
11117
11118            // Check to see if there are any update receivers to run.
11119            if (!mDidUpdate) {
11120                if (mWaitingUpdate) {
11121                    return;
11122                }
11123                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11124                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11125                    public void run() {
11126                        synchronized (ActivityManagerService.this) {
11127                            mDidUpdate = true;
11128                        }
11129                        writeLastDonePreBootReceivers(doneReceivers);
11130                        showBootMessage(mContext.getText(
11131                                R.string.android_upgrading_complete),
11132                                false);
11133                        systemReady(goingCallback);
11134                    }
11135                }, doneReceivers, UserHandle.USER_OWNER);
11136
11137                if (mWaitingUpdate) {
11138                    return;
11139                }
11140                mDidUpdate = true;
11141            }
11142
11143            mAppOpsService.systemReady();
11144            mSystemReady = true;
11145        }
11146
11147        ArrayList<ProcessRecord> procsToKill = null;
11148        synchronized(mPidsSelfLocked) {
11149            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11150                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11151                if (!isAllowedWhileBooting(proc.info)){
11152                    if (procsToKill == null) {
11153                        procsToKill = new ArrayList<ProcessRecord>();
11154                    }
11155                    procsToKill.add(proc);
11156                }
11157            }
11158        }
11159
11160        synchronized(this) {
11161            if (procsToKill != null) {
11162                for (int i=procsToKill.size()-1; i>=0; i--) {
11163                    ProcessRecord proc = procsToKill.get(i);
11164                    Slog.i(TAG, "Removing system update proc: " + proc);
11165                    removeProcessLocked(proc, true, false, "system update done");
11166                }
11167            }
11168
11169            // Now that we have cleaned up any update processes, we
11170            // are ready to start launching real processes and know that
11171            // we won't trample on them any more.
11172            mProcessesReady = true;
11173        }
11174
11175        Slog.i(TAG, "System now ready");
11176        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11177            SystemClock.uptimeMillis());
11178
11179        synchronized(this) {
11180            // Make sure we have no pre-ready processes sitting around.
11181
11182            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11183                ResolveInfo ri = mContext.getPackageManager()
11184                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11185                                STOCK_PM_FLAGS);
11186                CharSequence errorMsg = null;
11187                if (ri != null) {
11188                    ActivityInfo ai = ri.activityInfo;
11189                    ApplicationInfo app = ai.applicationInfo;
11190                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11191                        mTopAction = Intent.ACTION_FACTORY_TEST;
11192                        mTopData = null;
11193                        mTopComponent = new ComponentName(app.packageName,
11194                                ai.name);
11195                    } else {
11196                        errorMsg = mContext.getResources().getText(
11197                                com.android.internal.R.string.factorytest_not_system);
11198                    }
11199                } else {
11200                    errorMsg = mContext.getResources().getText(
11201                            com.android.internal.R.string.factorytest_no_action);
11202                }
11203                if (errorMsg != null) {
11204                    mTopAction = null;
11205                    mTopData = null;
11206                    mTopComponent = null;
11207                    Message msg = Message.obtain();
11208                    msg.what = SHOW_FACTORY_ERROR_MSG;
11209                    msg.getData().putCharSequence("msg", errorMsg);
11210                    mHandler.sendMessage(msg);
11211                }
11212            }
11213        }
11214
11215        retrieveSettings();
11216        loadResourcesOnSystemReady();
11217
11218        synchronized (this) {
11219            readGrantedUriPermissionsLocked();
11220        }
11221
11222        if (goingCallback != null) goingCallback.run();
11223
11224        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11225                Integer.toString(mCurrentUserId), mCurrentUserId);
11226        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11227                Integer.toString(mCurrentUserId), mCurrentUserId);
11228        mSystemServiceManager.startUser(mCurrentUserId);
11229
11230        synchronized (this) {
11231            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11232                try {
11233                    List apps = AppGlobals.getPackageManager().
11234                        getPersistentApplications(STOCK_PM_FLAGS);
11235                    if (apps != null) {
11236                        int N = apps.size();
11237                        int i;
11238                        for (i=0; i<N; i++) {
11239                            ApplicationInfo info
11240                                = (ApplicationInfo)apps.get(i);
11241                            if (info != null &&
11242                                    !info.packageName.equals("android")) {
11243                                addAppLocked(info, false, null /* ABI override */);
11244                            }
11245                        }
11246                    }
11247                } catch (RemoteException ex) {
11248                    // pm is in same process, this will never happen.
11249                }
11250            }
11251
11252            // Start up initial activity.
11253            mBooting = true;
11254            startHomeActivityLocked(mCurrentUserId);
11255
11256            try {
11257                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11258                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11259                            + " data partition or your device will be unstable.");
11260                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11261                }
11262            } catch (RemoteException e) {
11263            }
11264
11265            if (!Build.isFingerprintConsistent()) {
11266                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11267                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11268            }
11269
11270            long ident = Binder.clearCallingIdentity();
11271            try {
11272                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11273                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11274                        | Intent.FLAG_RECEIVER_FOREGROUND);
11275                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11276                broadcastIntentLocked(null, null, intent,
11277                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11278                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11279                intent = new Intent(Intent.ACTION_USER_STARTING);
11280                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11281                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11282                broadcastIntentLocked(null, null, intent,
11283                        null, new IIntentReceiver.Stub() {
11284                            @Override
11285                            public void performReceive(Intent intent, int resultCode, String data,
11286                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11287                                    throws RemoteException {
11288                            }
11289                        }, 0, null, null,
11290                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11291                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11292            } catch (Throwable t) {
11293                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11294            } finally {
11295                Binder.restoreCallingIdentity(ident);
11296            }
11297            mStackSupervisor.resumeTopActivitiesLocked();
11298            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11299        }
11300    }
11301
11302    private boolean makeAppCrashingLocked(ProcessRecord app,
11303            String shortMsg, String longMsg, String stackTrace) {
11304        app.crashing = true;
11305        app.crashingReport = generateProcessError(app,
11306                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11307        startAppProblemLocked(app);
11308        app.stopFreezingAllLocked();
11309        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11310    }
11311
11312    private void makeAppNotRespondingLocked(ProcessRecord app,
11313            String activity, String shortMsg, String longMsg) {
11314        app.notResponding = true;
11315        app.notRespondingReport = generateProcessError(app,
11316                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11317                activity, shortMsg, longMsg, null);
11318        startAppProblemLocked(app);
11319        app.stopFreezingAllLocked();
11320    }
11321
11322    /**
11323     * Generate a process error record, suitable for attachment to a ProcessRecord.
11324     *
11325     * @param app The ProcessRecord in which the error occurred.
11326     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11327     *                      ActivityManager.AppErrorStateInfo
11328     * @param activity The activity associated with the crash, if known.
11329     * @param shortMsg Short message describing the crash.
11330     * @param longMsg Long message describing the crash.
11331     * @param stackTrace Full crash stack trace, may be null.
11332     *
11333     * @return Returns a fully-formed AppErrorStateInfo record.
11334     */
11335    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11336            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11337        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11338
11339        report.condition = condition;
11340        report.processName = app.processName;
11341        report.pid = app.pid;
11342        report.uid = app.info.uid;
11343        report.tag = activity;
11344        report.shortMsg = shortMsg;
11345        report.longMsg = longMsg;
11346        report.stackTrace = stackTrace;
11347
11348        return report;
11349    }
11350
11351    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11352        synchronized (this) {
11353            app.crashing = false;
11354            app.crashingReport = null;
11355            app.notResponding = false;
11356            app.notRespondingReport = null;
11357            if (app.anrDialog == fromDialog) {
11358                app.anrDialog = null;
11359            }
11360            if (app.waitDialog == fromDialog) {
11361                app.waitDialog = null;
11362            }
11363            if (app.pid > 0 && app.pid != MY_PID) {
11364                handleAppCrashLocked(app, null, null, null);
11365                app.kill("user request after error", true);
11366            }
11367        }
11368    }
11369
11370    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11371            String stackTrace) {
11372        long now = SystemClock.uptimeMillis();
11373
11374        Long crashTime;
11375        if (!app.isolated) {
11376            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11377        } else {
11378            crashTime = null;
11379        }
11380        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11381            // This process loses!
11382            Slog.w(TAG, "Process " + app.info.processName
11383                    + " has crashed too many times: killing!");
11384            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11385                    app.userId, app.info.processName, app.uid);
11386            mStackSupervisor.handleAppCrashLocked(app);
11387            if (!app.persistent) {
11388                // We don't want to start this process again until the user
11389                // explicitly does so...  but for persistent process, we really
11390                // need to keep it running.  If a persistent process is actually
11391                // repeatedly crashing, then badness for everyone.
11392                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11393                        app.info.processName);
11394                if (!app.isolated) {
11395                    // XXX We don't have a way to mark isolated processes
11396                    // as bad, since they don't have a peristent identity.
11397                    mBadProcesses.put(app.info.processName, app.uid,
11398                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11399                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11400                }
11401                app.bad = true;
11402                app.removed = true;
11403                // Don't let services in this process be restarted and potentially
11404                // annoy the user repeatedly.  Unless it is persistent, since those
11405                // processes run critical code.
11406                removeProcessLocked(app, false, false, "crash");
11407                mStackSupervisor.resumeTopActivitiesLocked();
11408                return false;
11409            }
11410            mStackSupervisor.resumeTopActivitiesLocked();
11411        } else {
11412            mStackSupervisor.finishTopRunningActivityLocked(app);
11413        }
11414
11415        // Bump up the crash count of any services currently running in the proc.
11416        for (int i=app.services.size()-1; i>=0; i--) {
11417            // Any services running in the application need to be placed
11418            // back in the pending list.
11419            ServiceRecord sr = app.services.valueAt(i);
11420            sr.crashCount++;
11421        }
11422
11423        // If the crashing process is what we consider to be the "home process" and it has been
11424        // replaced by a third-party app, clear the package preferred activities from packages
11425        // with a home activity running in the process to prevent a repeatedly crashing app
11426        // from blocking the user to manually clear the list.
11427        final ArrayList<ActivityRecord> activities = app.activities;
11428        if (app == mHomeProcess && activities.size() > 0
11429                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11430            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11431                final ActivityRecord r = activities.get(activityNdx);
11432                if (r.isHomeActivity()) {
11433                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11434                    try {
11435                        ActivityThread.getPackageManager()
11436                                .clearPackagePreferredActivities(r.packageName);
11437                    } catch (RemoteException c) {
11438                        // pm is in same process, this will never happen.
11439                    }
11440                }
11441            }
11442        }
11443
11444        if (!app.isolated) {
11445            // XXX Can't keep track of crash times for isolated processes,
11446            // because they don't have a perisistent identity.
11447            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11448        }
11449
11450        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11451        return true;
11452    }
11453
11454    void startAppProblemLocked(ProcessRecord app) {
11455        // If this app is not running under the current user, then we
11456        // can't give it a report button because that would require
11457        // launching the report UI under a different user.
11458        app.errorReportReceiver = null;
11459
11460        for (int userId : mCurrentProfileIds) {
11461            if (app.userId == userId) {
11462                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11463                        mContext, app.info.packageName, app.info.flags);
11464            }
11465        }
11466        skipCurrentReceiverLocked(app);
11467    }
11468
11469    void skipCurrentReceiverLocked(ProcessRecord app) {
11470        for (BroadcastQueue queue : mBroadcastQueues) {
11471            queue.skipCurrentReceiverLocked(app);
11472        }
11473    }
11474
11475    /**
11476     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11477     * The application process will exit immediately after this call returns.
11478     * @param app object of the crashing app, null for the system server
11479     * @param crashInfo describing the exception
11480     */
11481    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11482        ProcessRecord r = findAppProcess(app, "Crash");
11483        final String processName = app == null ? "system_server"
11484                : (r == null ? "unknown" : r.processName);
11485
11486        handleApplicationCrashInner("crash", r, processName, crashInfo);
11487    }
11488
11489    /* Native crash reporting uses this inner version because it needs to be somewhat
11490     * decoupled from the AM-managed cleanup lifecycle
11491     */
11492    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11493            ApplicationErrorReport.CrashInfo crashInfo) {
11494        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11495                UserHandle.getUserId(Binder.getCallingUid()), processName,
11496                r == null ? -1 : r.info.flags,
11497                crashInfo.exceptionClassName,
11498                crashInfo.exceptionMessage,
11499                crashInfo.throwFileName,
11500                crashInfo.throwLineNumber);
11501
11502        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11503
11504        crashApplication(r, crashInfo);
11505    }
11506
11507    public void handleApplicationStrictModeViolation(
11508            IBinder app,
11509            int violationMask,
11510            StrictMode.ViolationInfo info) {
11511        ProcessRecord r = findAppProcess(app, "StrictMode");
11512        if (r == null) {
11513            return;
11514        }
11515
11516        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11517            Integer stackFingerprint = info.hashCode();
11518            boolean logIt = true;
11519            synchronized (mAlreadyLoggedViolatedStacks) {
11520                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11521                    logIt = false;
11522                    // TODO: sub-sample into EventLog for these, with
11523                    // the info.durationMillis?  Then we'd get
11524                    // the relative pain numbers, without logging all
11525                    // the stack traces repeatedly.  We'd want to do
11526                    // likewise in the client code, which also does
11527                    // dup suppression, before the Binder call.
11528                } else {
11529                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11530                        mAlreadyLoggedViolatedStacks.clear();
11531                    }
11532                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11533                }
11534            }
11535            if (logIt) {
11536                logStrictModeViolationToDropBox(r, info);
11537            }
11538        }
11539
11540        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11541            AppErrorResult result = new AppErrorResult();
11542            synchronized (this) {
11543                final long origId = Binder.clearCallingIdentity();
11544
11545                Message msg = Message.obtain();
11546                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11547                HashMap<String, Object> data = new HashMap<String, Object>();
11548                data.put("result", result);
11549                data.put("app", r);
11550                data.put("violationMask", violationMask);
11551                data.put("info", info);
11552                msg.obj = data;
11553                mHandler.sendMessage(msg);
11554
11555                Binder.restoreCallingIdentity(origId);
11556            }
11557            int res = result.get();
11558            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11559        }
11560    }
11561
11562    // Depending on the policy in effect, there could be a bunch of
11563    // these in quick succession so we try to batch these together to
11564    // minimize disk writes, number of dropbox entries, and maximize
11565    // compression, by having more fewer, larger records.
11566    private void logStrictModeViolationToDropBox(
11567            ProcessRecord process,
11568            StrictMode.ViolationInfo info) {
11569        if (info == null) {
11570            return;
11571        }
11572        final boolean isSystemApp = process == null ||
11573                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11574                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11575        final String processName = process == null ? "unknown" : process.processName;
11576        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11577        final DropBoxManager dbox = (DropBoxManager)
11578                mContext.getSystemService(Context.DROPBOX_SERVICE);
11579
11580        // Exit early if the dropbox isn't configured to accept this report type.
11581        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11582
11583        boolean bufferWasEmpty;
11584        boolean needsFlush;
11585        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11586        synchronized (sb) {
11587            bufferWasEmpty = sb.length() == 0;
11588            appendDropBoxProcessHeaders(process, processName, sb);
11589            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11590            sb.append("System-App: ").append(isSystemApp).append("\n");
11591            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11592            if (info.violationNumThisLoop != 0) {
11593                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11594            }
11595            if (info.numAnimationsRunning != 0) {
11596                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11597            }
11598            if (info.broadcastIntentAction != null) {
11599                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11600            }
11601            if (info.durationMillis != -1) {
11602                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11603            }
11604            if (info.numInstances != -1) {
11605                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11606            }
11607            if (info.tags != null) {
11608                for (String tag : info.tags) {
11609                    sb.append("Span-Tag: ").append(tag).append("\n");
11610                }
11611            }
11612            sb.append("\n");
11613            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11614                sb.append(info.crashInfo.stackTrace);
11615            }
11616            sb.append("\n");
11617
11618            // Only buffer up to ~64k.  Various logging bits truncate
11619            // things at 128k.
11620            needsFlush = (sb.length() > 64 * 1024);
11621        }
11622
11623        // Flush immediately if the buffer's grown too large, or this
11624        // is a non-system app.  Non-system apps are isolated with a
11625        // different tag & policy and not batched.
11626        //
11627        // Batching is useful during internal testing with
11628        // StrictMode settings turned up high.  Without batching,
11629        // thousands of separate files could be created on boot.
11630        if (!isSystemApp || needsFlush) {
11631            new Thread("Error dump: " + dropboxTag) {
11632                @Override
11633                public void run() {
11634                    String report;
11635                    synchronized (sb) {
11636                        report = sb.toString();
11637                        sb.delete(0, sb.length());
11638                        sb.trimToSize();
11639                    }
11640                    if (report.length() != 0) {
11641                        dbox.addText(dropboxTag, report);
11642                    }
11643                }
11644            }.start();
11645            return;
11646        }
11647
11648        // System app batching:
11649        if (!bufferWasEmpty) {
11650            // An existing dropbox-writing thread is outstanding, so
11651            // we don't need to start it up.  The existing thread will
11652            // catch the buffer appends we just did.
11653            return;
11654        }
11655
11656        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11657        // (After this point, we shouldn't access AMS internal data structures.)
11658        new Thread("Error dump: " + dropboxTag) {
11659            @Override
11660            public void run() {
11661                // 5 second sleep to let stacks arrive and be batched together
11662                try {
11663                    Thread.sleep(5000);  // 5 seconds
11664                } catch (InterruptedException e) {}
11665
11666                String errorReport;
11667                synchronized (mStrictModeBuffer) {
11668                    errorReport = mStrictModeBuffer.toString();
11669                    if (errorReport.length() == 0) {
11670                        return;
11671                    }
11672                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11673                    mStrictModeBuffer.trimToSize();
11674                }
11675                dbox.addText(dropboxTag, errorReport);
11676            }
11677        }.start();
11678    }
11679
11680    /**
11681     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11682     * @param app object of the crashing app, null for the system server
11683     * @param tag reported by the caller
11684     * @param system whether this wtf is coming from the system
11685     * @param crashInfo describing the context of the error
11686     * @return true if the process should exit immediately (WTF is fatal)
11687     */
11688    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11689            final ApplicationErrorReport.CrashInfo crashInfo) {
11690        final int callingUid = Binder.getCallingUid();
11691        final int callingPid = Binder.getCallingPid();
11692
11693        if (system) {
11694            // If this is coming from the system, we could very well have low-level
11695            // system locks held, so we want to do this all asynchronously.  And we
11696            // never want this to become fatal, so there is that too.
11697            mHandler.post(new Runnable() {
11698                @Override public void run() {
11699                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11700                }
11701            });
11702            return false;
11703        }
11704
11705        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11706                crashInfo);
11707
11708        if (r != null && r.pid != Process.myPid() &&
11709                Settings.Global.getInt(mContext.getContentResolver(),
11710                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11711            crashApplication(r, crashInfo);
11712            return true;
11713        } else {
11714            return false;
11715        }
11716    }
11717
11718    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11719            final ApplicationErrorReport.CrashInfo crashInfo) {
11720        final ProcessRecord r = findAppProcess(app, "WTF");
11721        final String processName = app == null ? "system_server"
11722                : (r == null ? "unknown" : r.processName);
11723
11724        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11725                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11726
11727        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11728
11729        return r;
11730    }
11731
11732    /**
11733     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11734     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11735     */
11736    private ProcessRecord findAppProcess(IBinder app, String reason) {
11737        if (app == null) {
11738            return null;
11739        }
11740
11741        synchronized (this) {
11742            final int NP = mProcessNames.getMap().size();
11743            for (int ip=0; ip<NP; ip++) {
11744                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11745                final int NA = apps.size();
11746                for (int ia=0; ia<NA; ia++) {
11747                    ProcessRecord p = apps.valueAt(ia);
11748                    if (p.thread != null && p.thread.asBinder() == app) {
11749                        return p;
11750                    }
11751                }
11752            }
11753
11754            Slog.w(TAG, "Can't find mystery application for " + reason
11755                    + " from pid=" + Binder.getCallingPid()
11756                    + " uid=" + Binder.getCallingUid() + ": " + app);
11757            return null;
11758        }
11759    }
11760
11761    /**
11762     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11763     * to append various headers to the dropbox log text.
11764     */
11765    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11766            StringBuilder sb) {
11767        // Watchdog thread ends up invoking this function (with
11768        // a null ProcessRecord) to add the stack file to dropbox.
11769        // Do not acquire a lock on this (am) in such cases, as it
11770        // could cause a potential deadlock, if and when watchdog
11771        // is invoked due to unavailability of lock on am and it
11772        // would prevent watchdog from killing system_server.
11773        if (process == null) {
11774            sb.append("Process: ").append(processName).append("\n");
11775            return;
11776        }
11777        // Note: ProcessRecord 'process' is guarded by the service
11778        // instance.  (notably process.pkgList, which could otherwise change
11779        // concurrently during execution of this method)
11780        synchronized (this) {
11781            sb.append("Process: ").append(processName).append("\n");
11782            int flags = process.info.flags;
11783            IPackageManager pm = AppGlobals.getPackageManager();
11784            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11785            for (int ip=0; ip<process.pkgList.size(); ip++) {
11786                String pkg = process.pkgList.keyAt(ip);
11787                sb.append("Package: ").append(pkg);
11788                try {
11789                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11790                    if (pi != null) {
11791                        sb.append(" v").append(pi.versionCode);
11792                        if (pi.versionName != null) {
11793                            sb.append(" (").append(pi.versionName).append(")");
11794                        }
11795                    }
11796                } catch (RemoteException e) {
11797                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11798                }
11799                sb.append("\n");
11800            }
11801        }
11802    }
11803
11804    private static String processClass(ProcessRecord process) {
11805        if (process == null || process.pid == MY_PID) {
11806            return "system_server";
11807        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11808            return "system_app";
11809        } else {
11810            return "data_app";
11811        }
11812    }
11813
11814    /**
11815     * Write a description of an error (crash, WTF, ANR) to the drop box.
11816     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11817     * @param process which caused the error, null means the system server
11818     * @param activity which triggered the error, null if unknown
11819     * @param parent activity related to the error, null if unknown
11820     * @param subject line related to the error, null if absent
11821     * @param report in long form describing the error, null if absent
11822     * @param logFile to include in the report, null if none
11823     * @param crashInfo giving an application stack trace, null if absent
11824     */
11825    public void addErrorToDropBox(String eventType,
11826            ProcessRecord process, String processName, ActivityRecord activity,
11827            ActivityRecord parent, String subject,
11828            final String report, final File logFile,
11829            final ApplicationErrorReport.CrashInfo crashInfo) {
11830        // NOTE -- this must never acquire the ActivityManagerService lock,
11831        // otherwise the watchdog may be prevented from resetting the system.
11832
11833        final String dropboxTag = processClass(process) + "_" + eventType;
11834        final DropBoxManager dbox = (DropBoxManager)
11835                mContext.getSystemService(Context.DROPBOX_SERVICE);
11836
11837        // Exit early if the dropbox isn't configured to accept this report type.
11838        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11839
11840        final StringBuilder sb = new StringBuilder(1024);
11841        appendDropBoxProcessHeaders(process, processName, sb);
11842        if (activity != null) {
11843            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11844        }
11845        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11846            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11847        }
11848        if (parent != null && parent != activity) {
11849            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11850        }
11851        if (subject != null) {
11852            sb.append("Subject: ").append(subject).append("\n");
11853        }
11854        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11855        if (Debug.isDebuggerConnected()) {
11856            sb.append("Debugger: Connected\n");
11857        }
11858        sb.append("\n");
11859
11860        // Do the rest in a worker thread to avoid blocking the caller on I/O
11861        // (After this point, we shouldn't access AMS internal data structures.)
11862        Thread worker = new Thread("Error dump: " + dropboxTag) {
11863            @Override
11864            public void run() {
11865                if (report != null) {
11866                    sb.append(report);
11867                }
11868                if (logFile != null) {
11869                    try {
11870                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11871                                    "\n\n[[TRUNCATED]]"));
11872                    } catch (IOException e) {
11873                        Slog.e(TAG, "Error reading " + logFile, e);
11874                    }
11875                }
11876                if (crashInfo != null && crashInfo.stackTrace != null) {
11877                    sb.append(crashInfo.stackTrace);
11878                }
11879
11880                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11881                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11882                if (lines > 0) {
11883                    sb.append("\n");
11884
11885                    // Merge several logcat streams, and take the last N lines
11886                    InputStreamReader input = null;
11887                    try {
11888                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11889                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11890                                "-b", "crash",
11891                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11892
11893                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11894                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11895                        input = new InputStreamReader(logcat.getInputStream());
11896
11897                        int num;
11898                        char[] buf = new char[8192];
11899                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11900                    } catch (IOException e) {
11901                        Slog.e(TAG, "Error running logcat", e);
11902                    } finally {
11903                        if (input != null) try { input.close(); } catch (IOException e) {}
11904                    }
11905                }
11906
11907                dbox.addText(dropboxTag, sb.toString());
11908            }
11909        };
11910
11911        if (process == null) {
11912            // If process is null, we are being called from some internal code
11913            // and may be about to die -- run this synchronously.
11914            worker.run();
11915        } else {
11916            worker.start();
11917        }
11918    }
11919
11920    /**
11921     * Bring up the "unexpected error" dialog box for a crashing app.
11922     * Deal with edge cases (intercepts from instrumented applications,
11923     * ActivityController, error intent receivers, that sort of thing).
11924     * @param r the application crashing
11925     * @param crashInfo describing the failure
11926     */
11927    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11928        long timeMillis = System.currentTimeMillis();
11929        String shortMsg = crashInfo.exceptionClassName;
11930        String longMsg = crashInfo.exceptionMessage;
11931        String stackTrace = crashInfo.stackTrace;
11932        if (shortMsg != null && longMsg != null) {
11933            longMsg = shortMsg + ": " + longMsg;
11934        } else if (shortMsg != null) {
11935            longMsg = shortMsg;
11936        }
11937
11938        AppErrorResult result = new AppErrorResult();
11939        synchronized (this) {
11940            if (mController != null) {
11941                try {
11942                    String name = r != null ? r.processName : null;
11943                    int pid = r != null ? r.pid : Binder.getCallingPid();
11944                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11945                    if (!mController.appCrashed(name, pid,
11946                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11947                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11948                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11949                            Slog.w(TAG, "Skip killing native crashed app " + name
11950                                    + "(" + pid + ") during testing");
11951                        } else {
11952                            Slog.w(TAG, "Force-killing crashed app " + name
11953                                    + " at watcher's request");
11954                            if (r != null) {
11955                                r.kill("crash", true);
11956                            } else {
11957                                // Huh.
11958                                Process.killProcess(pid);
11959                                Process.killProcessGroup(uid, pid);
11960                            }
11961                        }
11962                        return;
11963                    }
11964                } catch (RemoteException e) {
11965                    mController = null;
11966                    Watchdog.getInstance().setActivityController(null);
11967                }
11968            }
11969
11970            final long origId = Binder.clearCallingIdentity();
11971
11972            // If this process is running instrumentation, finish it.
11973            if (r != null && r.instrumentationClass != null) {
11974                Slog.w(TAG, "Error in app " + r.processName
11975                      + " running instrumentation " + r.instrumentationClass + ":");
11976                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11977                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11978                Bundle info = new Bundle();
11979                info.putString("shortMsg", shortMsg);
11980                info.putString("longMsg", longMsg);
11981                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11982                Binder.restoreCallingIdentity(origId);
11983                return;
11984            }
11985
11986            // If we can't identify the process or it's already exceeded its crash quota,
11987            // quit right away without showing a crash dialog.
11988            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11989                Binder.restoreCallingIdentity(origId);
11990                return;
11991            }
11992
11993            Message msg = Message.obtain();
11994            msg.what = SHOW_ERROR_MSG;
11995            HashMap data = new HashMap();
11996            data.put("result", result);
11997            data.put("app", r);
11998            msg.obj = data;
11999            mHandler.sendMessage(msg);
12000
12001            Binder.restoreCallingIdentity(origId);
12002        }
12003
12004        int res = result.get();
12005
12006        Intent appErrorIntent = null;
12007        synchronized (this) {
12008            if (r != null && !r.isolated) {
12009                // XXX Can't keep track of crash time for isolated processes,
12010                // since they don't have a persistent identity.
12011                mProcessCrashTimes.put(r.info.processName, r.uid,
12012                        SystemClock.uptimeMillis());
12013            }
12014            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12015                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12016            }
12017        }
12018
12019        if (appErrorIntent != null) {
12020            try {
12021                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12022            } catch (ActivityNotFoundException e) {
12023                Slog.w(TAG, "bug report receiver dissappeared", e);
12024            }
12025        }
12026    }
12027
12028    Intent createAppErrorIntentLocked(ProcessRecord r,
12029            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12030        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12031        if (report == null) {
12032            return null;
12033        }
12034        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12035        result.setComponent(r.errorReportReceiver);
12036        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12037        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12038        return result;
12039    }
12040
12041    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12042            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12043        if (r.errorReportReceiver == null) {
12044            return null;
12045        }
12046
12047        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12048            return null;
12049        }
12050
12051        ApplicationErrorReport report = new ApplicationErrorReport();
12052        report.packageName = r.info.packageName;
12053        report.installerPackageName = r.errorReportReceiver.getPackageName();
12054        report.processName = r.processName;
12055        report.time = timeMillis;
12056        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12057
12058        if (r.crashing || r.forceCrashReport) {
12059            report.type = ApplicationErrorReport.TYPE_CRASH;
12060            report.crashInfo = crashInfo;
12061        } else if (r.notResponding) {
12062            report.type = ApplicationErrorReport.TYPE_ANR;
12063            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12064
12065            report.anrInfo.activity = r.notRespondingReport.tag;
12066            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12067            report.anrInfo.info = r.notRespondingReport.longMsg;
12068        }
12069
12070        return report;
12071    }
12072
12073    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12074        enforceNotIsolatedCaller("getProcessesInErrorState");
12075        // assume our apps are happy - lazy create the list
12076        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12077
12078        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12079                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12080        int userId = UserHandle.getUserId(Binder.getCallingUid());
12081
12082        synchronized (this) {
12083
12084            // iterate across all processes
12085            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12086                ProcessRecord app = mLruProcesses.get(i);
12087                if (!allUsers && app.userId != userId) {
12088                    continue;
12089                }
12090                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12091                    // This one's in trouble, so we'll generate a report for it
12092                    // crashes are higher priority (in case there's a crash *and* an anr)
12093                    ActivityManager.ProcessErrorStateInfo report = null;
12094                    if (app.crashing) {
12095                        report = app.crashingReport;
12096                    } else if (app.notResponding) {
12097                        report = app.notRespondingReport;
12098                    }
12099
12100                    if (report != null) {
12101                        if (errList == null) {
12102                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12103                        }
12104                        errList.add(report);
12105                    } else {
12106                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12107                                " crashing = " + app.crashing +
12108                                " notResponding = " + app.notResponding);
12109                    }
12110                }
12111            }
12112        }
12113
12114        return errList;
12115    }
12116
12117    static int procStateToImportance(int procState, int memAdj,
12118            ActivityManager.RunningAppProcessInfo currApp) {
12119        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12120        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12121            currApp.lru = memAdj;
12122        } else {
12123            currApp.lru = 0;
12124        }
12125        return imp;
12126    }
12127
12128    private void fillInProcMemInfo(ProcessRecord app,
12129            ActivityManager.RunningAppProcessInfo outInfo) {
12130        outInfo.pid = app.pid;
12131        outInfo.uid = app.info.uid;
12132        if (mHeavyWeightProcess == app) {
12133            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12134        }
12135        if (app.persistent) {
12136            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12137        }
12138        if (app.activities.size() > 0) {
12139            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12140        }
12141        outInfo.lastTrimLevel = app.trimMemoryLevel;
12142        int adj = app.curAdj;
12143        int procState = app.curProcState;
12144        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12145        outInfo.importanceReasonCode = app.adjTypeCode;
12146        outInfo.processState = app.curProcState;
12147    }
12148
12149    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12150        enforceNotIsolatedCaller("getRunningAppProcesses");
12151        // Lazy instantiation of list
12152        List<ActivityManager.RunningAppProcessInfo> runList = null;
12153        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12154                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12155        int userId = UserHandle.getUserId(Binder.getCallingUid());
12156        synchronized (this) {
12157            // Iterate across all processes
12158            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12159                ProcessRecord app = mLruProcesses.get(i);
12160                if (!allUsers && app.userId != userId) {
12161                    continue;
12162                }
12163                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12164                    // Generate process state info for running application
12165                    ActivityManager.RunningAppProcessInfo currApp =
12166                        new ActivityManager.RunningAppProcessInfo(app.processName,
12167                                app.pid, app.getPackageList());
12168                    fillInProcMemInfo(app, currApp);
12169                    if (app.adjSource instanceof ProcessRecord) {
12170                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12171                        currApp.importanceReasonImportance =
12172                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12173                                        app.adjSourceProcState);
12174                    } else if (app.adjSource instanceof ActivityRecord) {
12175                        ActivityRecord r = (ActivityRecord)app.adjSource;
12176                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12177                    }
12178                    if (app.adjTarget instanceof ComponentName) {
12179                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12180                    }
12181                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12182                    //        + " lru=" + currApp.lru);
12183                    if (runList == null) {
12184                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12185                    }
12186                    runList.add(currApp);
12187                }
12188            }
12189        }
12190        return runList;
12191    }
12192
12193    public List<ApplicationInfo> getRunningExternalApplications() {
12194        enforceNotIsolatedCaller("getRunningExternalApplications");
12195        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12196        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12197        if (runningApps != null && runningApps.size() > 0) {
12198            Set<String> extList = new HashSet<String>();
12199            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12200                if (app.pkgList != null) {
12201                    for (String pkg : app.pkgList) {
12202                        extList.add(pkg);
12203                    }
12204                }
12205            }
12206            IPackageManager pm = AppGlobals.getPackageManager();
12207            for (String pkg : extList) {
12208                try {
12209                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12210                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12211                        retList.add(info);
12212                    }
12213                } catch (RemoteException e) {
12214                }
12215            }
12216        }
12217        return retList;
12218    }
12219
12220    @Override
12221    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12222        enforceNotIsolatedCaller("getMyMemoryState");
12223        synchronized (this) {
12224            ProcessRecord proc;
12225            synchronized (mPidsSelfLocked) {
12226                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12227            }
12228            fillInProcMemInfo(proc, outInfo);
12229        }
12230    }
12231
12232    @Override
12233    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12234        if (checkCallingPermission(android.Manifest.permission.DUMP)
12235                != PackageManager.PERMISSION_GRANTED) {
12236            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12237                    + Binder.getCallingPid()
12238                    + ", uid=" + Binder.getCallingUid()
12239                    + " without permission "
12240                    + android.Manifest.permission.DUMP);
12241            return;
12242        }
12243
12244        boolean dumpAll = false;
12245        boolean dumpClient = false;
12246        String dumpPackage = null;
12247
12248        int opti = 0;
12249        while (opti < args.length) {
12250            String opt = args[opti];
12251            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12252                break;
12253            }
12254            opti++;
12255            if ("-a".equals(opt)) {
12256                dumpAll = true;
12257            } else if ("-c".equals(opt)) {
12258                dumpClient = true;
12259            } else if ("-h".equals(opt)) {
12260                pw.println("Activity manager dump options:");
12261                pw.println("  [-a] [-c] [-h] [cmd] ...");
12262                pw.println("  cmd may be one of:");
12263                pw.println("    a[ctivities]: activity stack state");
12264                pw.println("    r[recents]: recent activities state");
12265                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12266                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12267                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12268                pw.println("    o[om]: out of memory management");
12269                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12270                pw.println("    provider [COMP_SPEC]: provider client-side state");
12271                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12272                pw.println("    service [COMP_SPEC]: service client-side state");
12273                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12274                pw.println("    all: dump all activities");
12275                pw.println("    top: dump the top activity");
12276                pw.println("    write: write all pending state to storage");
12277                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12278                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12279                pw.println("    a partial substring in a component name, a");
12280                pw.println("    hex object identifier.");
12281                pw.println("  -a: include all available server state.");
12282                pw.println("  -c: include client state.");
12283                return;
12284            } else {
12285                pw.println("Unknown argument: " + opt + "; use -h for help");
12286            }
12287        }
12288
12289        long origId = Binder.clearCallingIdentity();
12290        boolean more = false;
12291        // Is the caller requesting to dump a particular piece of data?
12292        if (opti < args.length) {
12293            String cmd = args[opti];
12294            opti++;
12295            if ("activities".equals(cmd) || "a".equals(cmd)) {
12296                synchronized (this) {
12297                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12298                }
12299            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12300                synchronized (this) {
12301                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12302                }
12303            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12304                String[] newArgs;
12305                String name;
12306                if (opti >= args.length) {
12307                    name = null;
12308                    newArgs = EMPTY_STRING_ARRAY;
12309                } else {
12310                    name = args[opti];
12311                    opti++;
12312                    newArgs = new String[args.length - opti];
12313                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12314                            args.length - opti);
12315                }
12316                synchronized (this) {
12317                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12318                }
12319            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12320                String[] newArgs;
12321                String name;
12322                if (opti >= args.length) {
12323                    name = null;
12324                    newArgs = EMPTY_STRING_ARRAY;
12325                } else {
12326                    name = args[opti];
12327                    opti++;
12328                    newArgs = new String[args.length - opti];
12329                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12330                            args.length - opti);
12331                }
12332                synchronized (this) {
12333                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12334                }
12335            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12336                String[] newArgs;
12337                String name;
12338                if (opti >= args.length) {
12339                    name = null;
12340                    newArgs = EMPTY_STRING_ARRAY;
12341                } else {
12342                    name = args[opti];
12343                    opti++;
12344                    newArgs = new String[args.length - opti];
12345                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12346                            args.length - opti);
12347                }
12348                synchronized (this) {
12349                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12350                }
12351            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12352                synchronized (this) {
12353                    dumpOomLocked(fd, pw, args, opti, true);
12354                }
12355            } else if ("provider".equals(cmd)) {
12356                String[] newArgs;
12357                String name;
12358                if (opti >= args.length) {
12359                    name = null;
12360                    newArgs = EMPTY_STRING_ARRAY;
12361                } else {
12362                    name = args[opti];
12363                    opti++;
12364                    newArgs = new String[args.length - opti];
12365                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12366                }
12367                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12368                    pw.println("No providers match: " + name);
12369                    pw.println("Use -h for help.");
12370                }
12371            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12372                synchronized (this) {
12373                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12374                }
12375            } else if ("service".equals(cmd)) {
12376                String[] newArgs;
12377                String name;
12378                if (opti >= args.length) {
12379                    name = null;
12380                    newArgs = EMPTY_STRING_ARRAY;
12381                } else {
12382                    name = args[opti];
12383                    opti++;
12384                    newArgs = new String[args.length - opti];
12385                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12386                            args.length - opti);
12387                }
12388                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12389                    pw.println("No services match: " + name);
12390                    pw.println("Use -h for help.");
12391                }
12392            } else if ("package".equals(cmd)) {
12393                String[] newArgs;
12394                if (opti >= args.length) {
12395                    pw.println("package: no package name specified");
12396                    pw.println("Use -h for help.");
12397                } else {
12398                    dumpPackage = args[opti];
12399                    opti++;
12400                    newArgs = new String[args.length - opti];
12401                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12402                            args.length - opti);
12403                    args = newArgs;
12404                    opti = 0;
12405                    more = true;
12406                }
12407            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12408                synchronized (this) {
12409                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12410                }
12411            } else if ("write".equals(cmd)) {
12412                mTaskPersister.flush();
12413                pw.println("All tasks persisted.");
12414                return;
12415            } else {
12416                // Dumping a single activity?
12417                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12418                    pw.println("Bad activity command, or no activities match: " + cmd);
12419                    pw.println("Use -h for help.");
12420                }
12421            }
12422            if (!more) {
12423                Binder.restoreCallingIdentity(origId);
12424                return;
12425            }
12426        }
12427
12428        // No piece of data specified, dump everything.
12429        synchronized (this) {
12430            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12431            pw.println();
12432            if (dumpAll) {
12433                pw.println("-------------------------------------------------------------------------------");
12434            }
12435            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12436            pw.println();
12437            if (dumpAll) {
12438                pw.println("-------------------------------------------------------------------------------");
12439            }
12440            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12441            pw.println();
12442            if (dumpAll) {
12443                pw.println("-------------------------------------------------------------------------------");
12444            }
12445            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12446            pw.println();
12447            if (dumpAll) {
12448                pw.println("-------------------------------------------------------------------------------");
12449            }
12450            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12451            pw.println();
12452            if (dumpAll) {
12453                pw.println("-------------------------------------------------------------------------------");
12454            }
12455            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12456            pw.println();
12457            if (dumpAll) {
12458                pw.println("-------------------------------------------------------------------------------");
12459            }
12460            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12461        }
12462        Binder.restoreCallingIdentity(origId);
12463    }
12464
12465    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12466            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12467        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12468
12469        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12470                dumpPackage);
12471        boolean needSep = printedAnything;
12472
12473        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12474                dumpPackage, needSep, "  mFocusedActivity: ");
12475        if (printed) {
12476            printedAnything = true;
12477            needSep = false;
12478        }
12479
12480        if (dumpPackage == null) {
12481            if (needSep) {
12482                pw.println();
12483            }
12484            needSep = true;
12485            printedAnything = true;
12486            mStackSupervisor.dump(pw, "  ");
12487        }
12488
12489        if (!printedAnything) {
12490            pw.println("  (nothing)");
12491        }
12492    }
12493
12494    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12495            int opti, boolean dumpAll, String dumpPackage) {
12496        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12497
12498        boolean printedAnything = false;
12499
12500        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12501            boolean printedHeader = false;
12502
12503            final int N = mRecentTasks.size();
12504            for (int i=0; i<N; i++) {
12505                TaskRecord tr = mRecentTasks.get(i);
12506                if (dumpPackage != null) {
12507                    if (tr.realActivity == null ||
12508                            !dumpPackage.equals(tr.realActivity)) {
12509                        continue;
12510                    }
12511                }
12512                if (!printedHeader) {
12513                    pw.println("  Recent tasks:");
12514                    printedHeader = true;
12515                    printedAnything = true;
12516                }
12517                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12518                        pw.println(tr);
12519                if (dumpAll) {
12520                    mRecentTasks.get(i).dump(pw, "    ");
12521                }
12522            }
12523        }
12524
12525        if (!printedAnything) {
12526            pw.println("  (nothing)");
12527        }
12528    }
12529
12530    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12531            int opti, boolean dumpAll, String dumpPackage) {
12532        boolean needSep = false;
12533        boolean printedAnything = false;
12534        int numPers = 0;
12535
12536        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12537
12538        if (dumpAll) {
12539            final int NP = mProcessNames.getMap().size();
12540            for (int ip=0; ip<NP; ip++) {
12541                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12542                final int NA = procs.size();
12543                for (int ia=0; ia<NA; ia++) {
12544                    ProcessRecord r = procs.valueAt(ia);
12545                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12546                        continue;
12547                    }
12548                    if (!needSep) {
12549                        pw.println("  All known processes:");
12550                        needSep = true;
12551                        printedAnything = true;
12552                    }
12553                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12554                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12555                        pw.print(" "); pw.println(r);
12556                    r.dump(pw, "    ");
12557                    if (r.persistent) {
12558                        numPers++;
12559                    }
12560                }
12561            }
12562        }
12563
12564        if (mIsolatedProcesses.size() > 0) {
12565            boolean printed = false;
12566            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12567                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12568                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12569                    continue;
12570                }
12571                if (!printed) {
12572                    if (needSep) {
12573                        pw.println();
12574                    }
12575                    pw.println("  Isolated process list (sorted by uid):");
12576                    printedAnything = true;
12577                    printed = true;
12578                    needSep = true;
12579                }
12580                pw.println(String.format("%sIsolated #%2d: %s",
12581                        "    ", i, r.toString()));
12582            }
12583        }
12584
12585        if (mLruProcesses.size() > 0) {
12586            if (needSep) {
12587                pw.println();
12588            }
12589            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12590                    pw.print(" total, non-act at ");
12591                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12592                    pw.print(", non-svc at ");
12593                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12594                    pw.println("):");
12595            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12596            needSep = true;
12597            printedAnything = true;
12598        }
12599
12600        if (dumpAll || dumpPackage != null) {
12601            synchronized (mPidsSelfLocked) {
12602                boolean printed = false;
12603                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12604                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12605                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12606                        continue;
12607                    }
12608                    if (!printed) {
12609                        if (needSep) pw.println();
12610                        needSep = true;
12611                        pw.println("  PID mappings:");
12612                        printed = true;
12613                        printedAnything = true;
12614                    }
12615                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12616                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12617                }
12618            }
12619        }
12620
12621        if (mForegroundProcesses.size() > 0) {
12622            synchronized (mPidsSelfLocked) {
12623                boolean printed = false;
12624                for (int i=0; i<mForegroundProcesses.size(); i++) {
12625                    ProcessRecord r = mPidsSelfLocked.get(
12626                            mForegroundProcesses.valueAt(i).pid);
12627                    if (dumpPackage != null && (r == null
12628                            || !r.pkgList.containsKey(dumpPackage))) {
12629                        continue;
12630                    }
12631                    if (!printed) {
12632                        if (needSep) pw.println();
12633                        needSep = true;
12634                        pw.println("  Foreground Processes:");
12635                        printed = true;
12636                        printedAnything = true;
12637                    }
12638                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12639                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12640                }
12641            }
12642        }
12643
12644        if (mPersistentStartingProcesses.size() > 0) {
12645            if (needSep) pw.println();
12646            needSep = true;
12647            printedAnything = true;
12648            pw.println("  Persisent processes that are starting:");
12649            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12650                    "Starting Norm", "Restarting PERS", dumpPackage);
12651        }
12652
12653        if (mRemovedProcesses.size() > 0) {
12654            if (needSep) pw.println();
12655            needSep = true;
12656            printedAnything = true;
12657            pw.println("  Processes that are being removed:");
12658            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12659                    "Removed Norm", "Removed PERS", dumpPackage);
12660        }
12661
12662        if (mProcessesOnHold.size() > 0) {
12663            if (needSep) pw.println();
12664            needSep = true;
12665            printedAnything = true;
12666            pw.println("  Processes that are on old until the system is ready:");
12667            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12668                    "OnHold Norm", "OnHold PERS", dumpPackage);
12669        }
12670
12671        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12672
12673        if (mProcessCrashTimes.getMap().size() > 0) {
12674            boolean printed = false;
12675            long now = SystemClock.uptimeMillis();
12676            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12677            final int NP = pmap.size();
12678            for (int ip=0; ip<NP; ip++) {
12679                String pname = pmap.keyAt(ip);
12680                SparseArray<Long> uids = pmap.valueAt(ip);
12681                final int N = uids.size();
12682                for (int i=0; i<N; i++) {
12683                    int puid = uids.keyAt(i);
12684                    ProcessRecord r = mProcessNames.get(pname, puid);
12685                    if (dumpPackage != null && (r == null
12686                            || !r.pkgList.containsKey(dumpPackage))) {
12687                        continue;
12688                    }
12689                    if (!printed) {
12690                        if (needSep) pw.println();
12691                        needSep = true;
12692                        pw.println("  Time since processes crashed:");
12693                        printed = true;
12694                        printedAnything = true;
12695                    }
12696                    pw.print("    Process "); pw.print(pname);
12697                            pw.print(" uid "); pw.print(puid);
12698                            pw.print(": last crashed ");
12699                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12700                            pw.println(" ago");
12701                }
12702            }
12703        }
12704
12705        if (mBadProcesses.getMap().size() > 0) {
12706            boolean printed = false;
12707            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12708            final int NP = pmap.size();
12709            for (int ip=0; ip<NP; ip++) {
12710                String pname = pmap.keyAt(ip);
12711                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12712                final int N = uids.size();
12713                for (int i=0; i<N; i++) {
12714                    int puid = uids.keyAt(i);
12715                    ProcessRecord r = mProcessNames.get(pname, puid);
12716                    if (dumpPackage != null && (r == null
12717                            || !r.pkgList.containsKey(dumpPackage))) {
12718                        continue;
12719                    }
12720                    if (!printed) {
12721                        if (needSep) pw.println();
12722                        needSep = true;
12723                        pw.println("  Bad processes:");
12724                        printedAnything = true;
12725                    }
12726                    BadProcessInfo info = uids.valueAt(i);
12727                    pw.print("    Bad process "); pw.print(pname);
12728                            pw.print(" uid "); pw.print(puid);
12729                            pw.print(": crashed at time "); pw.println(info.time);
12730                    if (info.shortMsg != null) {
12731                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12732                    }
12733                    if (info.longMsg != null) {
12734                        pw.print("      Long msg: "); pw.println(info.longMsg);
12735                    }
12736                    if (info.stack != null) {
12737                        pw.println("      Stack:");
12738                        int lastPos = 0;
12739                        for (int pos=0; pos<info.stack.length(); pos++) {
12740                            if (info.stack.charAt(pos) == '\n') {
12741                                pw.print("        ");
12742                                pw.write(info.stack, lastPos, pos-lastPos);
12743                                pw.println();
12744                                lastPos = pos+1;
12745                            }
12746                        }
12747                        if (lastPos < info.stack.length()) {
12748                            pw.print("        ");
12749                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12750                            pw.println();
12751                        }
12752                    }
12753                }
12754            }
12755        }
12756
12757        if (dumpPackage == null) {
12758            pw.println();
12759            needSep = false;
12760            pw.println("  mStartedUsers:");
12761            for (int i=0; i<mStartedUsers.size(); i++) {
12762                UserStartedState uss = mStartedUsers.valueAt(i);
12763                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12764                        pw.print(": "); uss.dump("", pw);
12765            }
12766            pw.print("  mStartedUserArray: [");
12767            for (int i=0; i<mStartedUserArray.length; i++) {
12768                if (i > 0) pw.print(", ");
12769                pw.print(mStartedUserArray[i]);
12770            }
12771            pw.println("]");
12772            pw.print("  mUserLru: [");
12773            for (int i=0; i<mUserLru.size(); i++) {
12774                if (i > 0) pw.print(", ");
12775                pw.print(mUserLru.get(i));
12776            }
12777            pw.println("]");
12778            if (dumpAll) {
12779                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12780            }
12781            synchronized (mUserProfileGroupIdsSelfLocked) {
12782                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12783                    pw.println("  mUserProfileGroupIds:");
12784                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12785                        pw.print("    User #");
12786                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12787                        pw.print(" -> profile #");
12788                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12789                    }
12790                }
12791            }
12792        }
12793        if (mHomeProcess != null && (dumpPackage == null
12794                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12795            if (needSep) {
12796                pw.println();
12797                needSep = false;
12798            }
12799            pw.println("  mHomeProcess: " + mHomeProcess);
12800        }
12801        if (mPreviousProcess != null && (dumpPackage == null
12802                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12803            if (needSep) {
12804                pw.println();
12805                needSep = false;
12806            }
12807            pw.println("  mPreviousProcess: " + mPreviousProcess);
12808        }
12809        if (dumpAll) {
12810            StringBuilder sb = new StringBuilder(128);
12811            sb.append("  mPreviousProcessVisibleTime: ");
12812            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12813            pw.println(sb);
12814        }
12815        if (mHeavyWeightProcess != null && (dumpPackage == null
12816                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12817            if (needSep) {
12818                pw.println();
12819                needSep = false;
12820            }
12821            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12822        }
12823        if (dumpPackage == null) {
12824            pw.println("  mConfiguration: " + mConfiguration);
12825        }
12826        if (dumpAll) {
12827            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12828            if (mCompatModePackages.getPackages().size() > 0) {
12829                boolean printed = false;
12830                for (Map.Entry<String, Integer> entry
12831                        : mCompatModePackages.getPackages().entrySet()) {
12832                    String pkg = entry.getKey();
12833                    int mode = entry.getValue();
12834                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12835                        continue;
12836                    }
12837                    if (!printed) {
12838                        pw.println("  mScreenCompatPackages:");
12839                        printed = true;
12840                    }
12841                    pw.print("    "); pw.print(pkg); pw.print(": ");
12842                            pw.print(mode); pw.println();
12843                }
12844            }
12845        }
12846        if (dumpPackage == null) {
12847            if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) {
12848                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12849                        + " mLockScreenShown " + lockScreenShownToString());
12850            }
12851            if (mShuttingDown || mRunningVoice) {
12852                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12853            }
12854        }
12855        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12856                || mOrigWaitForDebugger) {
12857            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12858                    || dumpPackage.equals(mOrigDebugApp)) {
12859                if (needSep) {
12860                    pw.println();
12861                    needSep = false;
12862                }
12863                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12864                        + " mDebugTransient=" + mDebugTransient
12865                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12866            }
12867        }
12868        if (mOpenGlTraceApp != null) {
12869            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12870                if (needSep) {
12871                    pw.println();
12872                    needSep = false;
12873                }
12874                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12875            }
12876        }
12877        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12878                || mProfileFd != null) {
12879            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12880                if (needSep) {
12881                    pw.println();
12882                    needSep = false;
12883                }
12884                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12885                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12886                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12887                        + mAutoStopProfiler);
12888                pw.println("  mProfileType=" + mProfileType);
12889            }
12890        }
12891        if (dumpPackage == null) {
12892            if (mAlwaysFinishActivities || mController != null) {
12893                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12894                        + " mController=" + mController);
12895            }
12896            if (dumpAll) {
12897                pw.println("  Total persistent processes: " + numPers);
12898                pw.println("  mProcessesReady=" + mProcessesReady
12899                        + " mSystemReady=" + mSystemReady
12900                        + " mBooted=" + mBooted
12901                        + " mFactoryTest=" + mFactoryTest);
12902                pw.println("  mBooting=" + mBooting
12903                        + " mCallFinishBooting=" + mCallFinishBooting
12904                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12905                pw.print("  mLastPowerCheckRealtime=");
12906                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12907                        pw.println("");
12908                pw.print("  mLastPowerCheckUptime=");
12909                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12910                        pw.println("");
12911                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12912                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12913                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12914                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12915                        + " (" + mLruProcesses.size() + " total)"
12916                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12917                        + " mNumServiceProcs=" + mNumServiceProcs
12918                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12919                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12920                        + " mLastMemoryLevel" + mLastMemoryLevel
12921                        + " mLastNumProcesses" + mLastNumProcesses);
12922                long now = SystemClock.uptimeMillis();
12923                pw.print("  mLastIdleTime=");
12924                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12925                        pw.print(" mLowRamSinceLastIdle=");
12926                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12927                        pw.println();
12928            }
12929        }
12930
12931        if (!printedAnything) {
12932            pw.println("  (nothing)");
12933        }
12934    }
12935
12936    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12937            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12938        if (mProcessesToGc.size() > 0) {
12939            boolean printed = false;
12940            long now = SystemClock.uptimeMillis();
12941            for (int i=0; i<mProcessesToGc.size(); i++) {
12942                ProcessRecord proc = mProcessesToGc.get(i);
12943                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12944                    continue;
12945                }
12946                if (!printed) {
12947                    if (needSep) pw.println();
12948                    needSep = true;
12949                    pw.println("  Processes that are waiting to GC:");
12950                    printed = true;
12951                }
12952                pw.print("    Process "); pw.println(proc);
12953                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12954                        pw.print(", last gced=");
12955                        pw.print(now-proc.lastRequestedGc);
12956                        pw.print(" ms ago, last lowMem=");
12957                        pw.print(now-proc.lastLowMemory);
12958                        pw.println(" ms ago");
12959
12960            }
12961        }
12962        return needSep;
12963    }
12964
12965    void printOomLevel(PrintWriter pw, String name, int adj) {
12966        pw.print("    ");
12967        if (adj >= 0) {
12968            pw.print(' ');
12969            if (adj < 10) pw.print(' ');
12970        } else {
12971            if (adj > -10) pw.print(' ');
12972        }
12973        pw.print(adj);
12974        pw.print(": ");
12975        pw.print(name);
12976        pw.print(" (");
12977        pw.print(mProcessList.getMemLevel(adj)/1024);
12978        pw.println(" kB)");
12979    }
12980
12981    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12982            int opti, boolean dumpAll) {
12983        boolean needSep = false;
12984
12985        if (mLruProcesses.size() > 0) {
12986            if (needSep) pw.println();
12987            needSep = true;
12988            pw.println("  OOM levels:");
12989            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12990            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12991            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12992            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12993            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12994            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12995            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12996            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12997            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12998            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12999            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13000            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13001            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13002            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13003
13004            if (needSep) pw.println();
13005            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13006                    pw.print(" total, non-act at ");
13007                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13008                    pw.print(", non-svc at ");
13009                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13010                    pw.println("):");
13011            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13012            needSep = true;
13013        }
13014
13015        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13016
13017        pw.println();
13018        pw.println("  mHomeProcess: " + mHomeProcess);
13019        pw.println("  mPreviousProcess: " + mPreviousProcess);
13020        if (mHeavyWeightProcess != null) {
13021            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13022        }
13023
13024        return true;
13025    }
13026
13027    /**
13028     * There are three ways to call this:
13029     *  - no provider specified: dump all the providers
13030     *  - a flattened component name that matched an existing provider was specified as the
13031     *    first arg: dump that one provider
13032     *  - the first arg isn't the flattened component name of an existing provider:
13033     *    dump all providers whose component contains the first arg as a substring
13034     */
13035    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13036            int opti, boolean dumpAll) {
13037        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13038    }
13039
13040    static class ItemMatcher {
13041        ArrayList<ComponentName> components;
13042        ArrayList<String> strings;
13043        ArrayList<Integer> objects;
13044        boolean all;
13045
13046        ItemMatcher() {
13047            all = true;
13048        }
13049
13050        void build(String name) {
13051            ComponentName componentName = ComponentName.unflattenFromString(name);
13052            if (componentName != null) {
13053                if (components == null) {
13054                    components = new ArrayList<ComponentName>();
13055                }
13056                components.add(componentName);
13057                all = false;
13058            } else {
13059                int objectId = 0;
13060                // Not a '/' separated full component name; maybe an object ID?
13061                try {
13062                    objectId = Integer.parseInt(name, 16);
13063                    if (objects == null) {
13064                        objects = new ArrayList<Integer>();
13065                    }
13066                    objects.add(objectId);
13067                    all = false;
13068                } catch (RuntimeException e) {
13069                    // Not an integer; just do string match.
13070                    if (strings == null) {
13071                        strings = new ArrayList<String>();
13072                    }
13073                    strings.add(name);
13074                    all = false;
13075                }
13076            }
13077        }
13078
13079        int build(String[] args, int opti) {
13080            for (; opti<args.length; opti++) {
13081                String name = args[opti];
13082                if ("--".equals(name)) {
13083                    return opti+1;
13084                }
13085                build(name);
13086            }
13087            return opti;
13088        }
13089
13090        boolean match(Object object, ComponentName comp) {
13091            if (all) {
13092                return true;
13093            }
13094            if (components != null) {
13095                for (int i=0; i<components.size(); i++) {
13096                    if (components.get(i).equals(comp)) {
13097                        return true;
13098                    }
13099                }
13100            }
13101            if (objects != null) {
13102                for (int i=0; i<objects.size(); i++) {
13103                    if (System.identityHashCode(object) == objects.get(i)) {
13104                        return true;
13105                    }
13106                }
13107            }
13108            if (strings != null) {
13109                String flat = comp.flattenToString();
13110                for (int i=0; i<strings.size(); i++) {
13111                    if (flat.contains(strings.get(i))) {
13112                        return true;
13113                    }
13114                }
13115            }
13116            return false;
13117        }
13118    }
13119
13120    /**
13121     * There are three things that cmd can be:
13122     *  - a flattened component name that matches an existing activity
13123     *  - the cmd arg isn't the flattened component name of an existing activity:
13124     *    dump all activity whose component contains the cmd as a substring
13125     *  - A hex number of the ActivityRecord object instance.
13126     */
13127    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13128            int opti, boolean dumpAll) {
13129        ArrayList<ActivityRecord> activities;
13130
13131        synchronized (this) {
13132            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13133        }
13134
13135        if (activities.size() <= 0) {
13136            return false;
13137        }
13138
13139        String[] newArgs = new String[args.length - opti];
13140        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13141
13142        TaskRecord lastTask = null;
13143        boolean needSep = false;
13144        for (int i=activities.size()-1; i>=0; i--) {
13145            ActivityRecord r = activities.get(i);
13146            if (needSep) {
13147                pw.println();
13148            }
13149            needSep = true;
13150            synchronized (this) {
13151                if (lastTask != r.task) {
13152                    lastTask = r.task;
13153                    pw.print("TASK "); pw.print(lastTask.affinity);
13154                            pw.print(" id="); pw.println(lastTask.taskId);
13155                    if (dumpAll) {
13156                        lastTask.dump(pw, "  ");
13157                    }
13158                }
13159            }
13160            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13161        }
13162        return true;
13163    }
13164
13165    /**
13166     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13167     * there is a thread associated with the activity.
13168     */
13169    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13170            final ActivityRecord r, String[] args, boolean dumpAll) {
13171        String innerPrefix = prefix + "  ";
13172        synchronized (this) {
13173            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13174                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13175                    pw.print(" pid=");
13176                    if (r.app != null) pw.println(r.app.pid);
13177                    else pw.println("(not running)");
13178            if (dumpAll) {
13179                r.dump(pw, innerPrefix);
13180            }
13181        }
13182        if (r.app != null && r.app.thread != null) {
13183            // flush anything that is already in the PrintWriter since the thread is going
13184            // to write to the file descriptor directly
13185            pw.flush();
13186            try {
13187                TransferPipe tp = new TransferPipe();
13188                try {
13189                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13190                            r.appToken, innerPrefix, args);
13191                    tp.go(fd);
13192                } finally {
13193                    tp.kill();
13194                }
13195            } catch (IOException e) {
13196                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13197            } catch (RemoteException e) {
13198                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13199            }
13200        }
13201    }
13202
13203    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13204            int opti, boolean dumpAll, String dumpPackage) {
13205        boolean needSep = false;
13206        boolean onlyHistory = false;
13207        boolean printedAnything = false;
13208
13209        if ("history".equals(dumpPackage)) {
13210            if (opti < args.length && "-s".equals(args[opti])) {
13211                dumpAll = false;
13212            }
13213            onlyHistory = true;
13214            dumpPackage = null;
13215        }
13216
13217        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13218        if (!onlyHistory && dumpAll) {
13219            if (mRegisteredReceivers.size() > 0) {
13220                boolean printed = false;
13221                Iterator it = mRegisteredReceivers.values().iterator();
13222                while (it.hasNext()) {
13223                    ReceiverList r = (ReceiverList)it.next();
13224                    if (dumpPackage != null && (r.app == null ||
13225                            !dumpPackage.equals(r.app.info.packageName))) {
13226                        continue;
13227                    }
13228                    if (!printed) {
13229                        pw.println("  Registered Receivers:");
13230                        needSep = true;
13231                        printed = true;
13232                        printedAnything = true;
13233                    }
13234                    pw.print("  * "); pw.println(r);
13235                    r.dump(pw, "    ");
13236                }
13237            }
13238
13239            if (mReceiverResolver.dump(pw, needSep ?
13240                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13241                    "    ", dumpPackage, false)) {
13242                needSep = true;
13243                printedAnything = true;
13244            }
13245        }
13246
13247        for (BroadcastQueue q : mBroadcastQueues) {
13248            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13249            printedAnything |= needSep;
13250        }
13251
13252        needSep = true;
13253
13254        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13255            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13256                if (needSep) {
13257                    pw.println();
13258                }
13259                needSep = true;
13260                printedAnything = true;
13261                pw.print("  Sticky broadcasts for user ");
13262                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13263                StringBuilder sb = new StringBuilder(128);
13264                for (Map.Entry<String, ArrayList<Intent>> ent
13265                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13266                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13267                    if (dumpAll) {
13268                        pw.println(":");
13269                        ArrayList<Intent> intents = ent.getValue();
13270                        final int N = intents.size();
13271                        for (int i=0; i<N; i++) {
13272                            sb.setLength(0);
13273                            sb.append("    Intent: ");
13274                            intents.get(i).toShortString(sb, false, true, false, false);
13275                            pw.println(sb.toString());
13276                            Bundle bundle = intents.get(i).getExtras();
13277                            if (bundle != null) {
13278                                pw.print("      ");
13279                                pw.println(bundle.toString());
13280                            }
13281                        }
13282                    } else {
13283                        pw.println("");
13284                    }
13285                }
13286            }
13287        }
13288
13289        if (!onlyHistory && dumpAll) {
13290            pw.println();
13291            for (BroadcastQueue queue : mBroadcastQueues) {
13292                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13293                        + queue.mBroadcastsScheduled);
13294            }
13295            pw.println("  mHandler:");
13296            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13297            needSep = true;
13298            printedAnything = true;
13299        }
13300
13301        if (!printedAnything) {
13302            pw.println("  (nothing)");
13303        }
13304    }
13305
13306    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13307            int opti, boolean dumpAll, String dumpPackage) {
13308        boolean needSep;
13309        boolean printedAnything = false;
13310
13311        ItemMatcher matcher = new ItemMatcher();
13312        matcher.build(args, opti);
13313
13314        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13315
13316        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13317        printedAnything |= needSep;
13318
13319        if (mLaunchingProviders.size() > 0) {
13320            boolean printed = false;
13321            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13322                ContentProviderRecord r = mLaunchingProviders.get(i);
13323                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13324                    continue;
13325                }
13326                if (!printed) {
13327                    if (needSep) pw.println();
13328                    needSep = true;
13329                    pw.println("  Launching content providers:");
13330                    printed = true;
13331                    printedAnything = true;
13332                }
13333                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13334                        pw.println(r);
13335            }
13336        }
13337
13338        if (mGrantedUriPermissions.size() > 0) {
13339            boolean printed = false;
13340            int dumpUid = -2;
13341            if (dumpPackage != null) {
13342                try {
13343                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13344                } catch (NameNotFoundException e) {
13345                    dumpUid = -1;
13346                }
13347            }
13348            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13349                int uid = mGrantedUriPermissions.keyAt(i);
13350                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13351                    continue;
13352                }
13353                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13354                if (!printed) {
13355                    if (needSep) pw.println();
13356                    needSep = true;
13357                    pw.println("  Granted Uri Permissions:");
13358                    printed = true;
13359                    printedAnything = true;
13360                }
13361                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13362                for (UriPermission perm : perms.values()) {
13363                    pw.print("    "); pw.println(perm);
13364                    if (dumpAll) {
13365                        perm.dump(pw, "      ");
13366                    }
13367                }
13368            }
13369        }
13370
13371        if (!printedAnything) {
13372            pw.println("  (nothing)");
13373        }
13374    }
13375
13376    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13377            int opti, boolean dumpAll, String dumpPackage) {
13378        boolean printed = false;
13379
13380        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13381
13382        if (mIntentSenderRecords.size() > 0) {
13383            Iterator<WeakReference<PendingIntentRecord>> it
13384                    = mIntentSenderRecords.values().iterator();
13385            while (it.hasNext()) {
13386                WeakReference<PendingIntentRecord> ref = it.next();
13387                PendingIntentRecord rec = ref != null ? ref.get(): null;
13388                if (dumpPackage != null && (rec == null
13389                        || !dumpPackage.equals(rec.key.packageName))) {
13390                    continue;
13391                }
13392                printed = true;
13393                if (rec != null) {
13394                    pw.print("  * "); pw.println(rec);
13395                    if (dumpAll) {
13396                        rec.dump(pw, "    ");
13397                    }
13398                } else {
13399                    pw.print("  * "); pw.println(ref);
13400                }
13401            }
13402        }
13403
13404        if (!printed) {
13405            pw.println("  (nothing)");
13406        }
13407    }
13408
13409    private static final int dumpProcessList(PrintWriter pw,
13410            ActivityManagerService service, List list,
13411            String prefix, String normalLabel, String persistentLabel,
13412            String dumpPackage) {
13413        int numPers = 0;
13414        final int N = list.size()-1;
13415        for (int i=N; i>=0; i--) {
13416            ProcessRecord r = (ProcessRecord)list.get(i);
13417            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13418                continue;
13419            }
13420            pw.println(String.format("%s%s #%2d: %s",
13421                    prefix, (r.persistent ? persistentLabel : normalLabel),
13422                    i, r.toString()));
13423            if (r.persistent) {
13424                numPers++;
13425            }
13426        }
13427        return numPers;
13428    }
13429
13430    private static final boolean dumpProcessOomList(PrintWriter pw,
13431            ActivityManagerService service, List<ProcessRecord> origList,
13432            String prefix, String normalLabel, String persistentLabel,
13433            boolean inclDetails, String dumpPackage) {
13434
13435        ArrayList<Pair<ProcessRecord, Integer>> list
13436                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13437        for (int i=0; i<origList.size(); i++) {
13438            ProcessRecord r = origList.get(i);
13439            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13440                continue;
13441            }
13442            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13443        }
13444
13445        if (list.size() <= 0) {
13446            return false;
13447        }
13448
13449        Comparator<Pair<ProcessRecord, Integer>> comparator
13450                = new Comparator<Pair<ProcessRecord, Integer>>() {
13451            @Override
13452            public int compare(Pair<ProcessRecord, Integer> object1,
13453                    Pair<ProcessRecord, Integer> object2) {
13454                if (object1.first.setAdj != object2.first.setAdj) {
13455                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13456                }
13457                if (object1.second.intValue() != object2.second.intValue()) {
13458                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13459                }
13460                return 0;
13461            }
13462        };
13463
13464        Collections.sort(list, comparator);
13465
13466        final long curRealtime = SystemClock.elapsedRealtime();
13467        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13468        final long curUptime = SystemClock.uptimeMillis();
13469        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13470
13471        for (int i=list.size()-1; i>=0; i--) {
13472            ProcessRecord r = list.get(i).first;
13473            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13474            char schedGroup;
13475            switch (r.setSchedGroup) {
13476                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13477                    schedGroup = 'B';
13478                    break;
13479                case Process.THREAD_GROUP_DEFAULT:
13480                    schedGroup = 'F';
13481                    break;
13482                default:
13483                    schedGroup = '?';
13484                    break;
13485            }
13486            char foreground;
13487            if (r.foregroundActivities) {
13488                foreground = 'A';
13489            } else if (r.foregroundServices) {
13490                foreground = 'S';
13491            } else {
13492                foreground = ' ';
13493            }
13494            String procState = ProcessList.makeProcStateString(r.curProcState);
13495            pw.print(prefix);
13496            pw.print(r.persistent ? persistentLabel : normalLabel);
13497            pw.print(" #");
13498            int num = (origList.size()-1)-list.get(i).second;
13499            if (num < 10) pw.print(' ');
13500            pw.print(num);
13501            pw.print(": ");
13502            pw.print(oomAdj);
13503            pw.print(' ');
13504            pw.print(schedGroup);
13505            pw.print('/');
13506            pw.print(foreground);
13507            pw.print('/');
13508            pw.print(procState);
13509            pw.print(" trm:");
13510            if (r.trimMemoryLevel < 10) pw.print(' ');
13511            pw.print(r.trimMemoryLevel);
13512            pw.print(' ');
13513            pw.print(r.toShortString());
13514            pw.print(" (");
13515            pw.print(r.adjType);
13516            pw.println(')');
13517            if (r.adjSource != null || r.adjTarget != null) {
13518                pw.print(prefix);
13519                pw.print("    ");
13520                if (r.adjTarget instanceof ComponentName) {
13521                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13522                } else if (r.adjTarget != null) {
13523                    pw.print(r.adjTarget.toString());
13524                } else {
13525                    pw.print("{null}");
13526                }
13527                pw.print("<=");
13528                if (r.adjSource instanceof ProcessRecord) {
13529                    pw.print("Proc{");
13530                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13531                    pw.println("}");
13532                } else if (r.adjSource != null) {
13533                    pw.println(r.adjSource.toString());
13534                } else {
13535                    pw.println("{null}");
13536                }
13537            }
13538            if (inclDetails) {
13539                pw.print(prefix);
13540                pw.print("    ");
13541                pw.print("oom: max="); pw.print(r.maxAdj);
13542                pw.print(" curRaw="); pw.print(r.curRawAdj);
13543                pw.print(" setRaw="); pw.print(r.setRawAdj);
13544                pw.print(" cur="); pw.print(r.curAdj);
13545                pw.print(" set="); pw.println(r.setAdj);
13546                pw.print(prefix);
13547                pw.print("    ");
13548                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13549                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13550                pw.print(" lastPss="); pw.print(r.lastPss);
13551                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13552                pw.print(prefix);
13553                pw.print("    ");
13554                pw.print("cached="); pw.print(r.cached);
13555                pw.print(" empty="); pw.print(r.empty);
13556                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13557
13558                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13559                    if (r.lastWakeTime != 0) {
13560                        long wtime;
13561                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13562                        synchronized (stats) {
13563                            wtime = stats.getProcessWakeTime(r.info.uid,
13564                                    r.pid, curRealtime);
13565                        }
13566                        long timeUsed = wtime - r.lastWakeTime;
13567                        pw.print(prefix);
13568                        pw.print("    ");
13569                        pw.print("keep awake over ");
13570                        TimeUtils.formatDuration(realtimeSince, pw);
13571                        pw.print(" used ");
13572                        TimeUtils.formatDuration(timeUsed, pw);
13573                        pw.print(" (");
13574                        pw.print((timeUsed*100)/realtimeSince);
13575                        pw.println("%)");
13576                    }
13577                    if (r.lastCpuTime != 0) {
13578                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13579                        pw.print(prefix);
13580                        pw.print("    ");
13581                        pw.print("run cpu over ");
13582                        TimeUtils.formatDuration(uptimeSince, pw);
13583                        pw.print(" used ");
13584                        TimeUtils.formatDuration(timeUsed, pw);
13585                        pw.print(" (");
13586                        pw.print((timeUsed*100)/uptimeSince);
13587                        pw.println("%)");
13588                    }
13589                }
13590            }
13591        }
13592        return true;
13593    }
13594
13595    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13596            String[] args) {
13597        ArrayList<ProcessRecord> procs;
13598        synchronized (this) {
13599            if (args != null && args.length > start
13600                    && args[start].charAt(0) != '-') {
13601                procs = new ArrayList<ProcessRecord>();
13602                int pid = -1;
13603                try {
13604                    pid = Integer.parseInt(args[start]);
13605                } catch (NumberFormatException e) {
13606                }
13607                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13608                    ProcessRecord proc = mLruProcesses.get(i);
13609                    if (proc.pid == pid) {
13610                        procs.add(proc);
13611                    } else if (allPkgs && proc.pkgList != null
13612                            && proc.pkgList.containsKey(args[start])) {
13613                        procs.add(proc);
13614                    } else if (proc.processName.equals(args[start])) {
13615                        procs.add(proc);
13616                    }
13617                }
13618                if (procs.size() <= 0) {
13619                    return null;
13620                }
13621            } else {
13622                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13623            }
13624        }
13625        return procs;
13626    }
13627
13628    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13629            PrintWriter pw, String[] args) {
13630        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13631        if (procs == null) {
13632            pw.println("No process found for: " + args[0]);
13633            return;
13634        }
13635
13636        long uptime = SystemClock.uptimeMillis();
13637        long realtime = SystemClock.elapsedRealtime();
13638        pw.println("Applications Graphics Acceleration Info:");
13639        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13640
13641        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13642            ProcessRecord r = procs.get(i);
13643            if (r.thread != null) {
13644                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13645                pw.flush();
13646                try {
13647                    TransferPipe tp = new TransferPipe();
13648                    try {
13649                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13650                        tp.go(fd);
13651                    } finally {
13652                        tp.kill();
13653                    }
13654                } catch (IOException e) {
13655                    pw.println("Failure while dumping the app: " + r);
13656                    pw.flush();
13657                } catch (RemoteException e) {
13658                    pw.println("Got a RemoteException while dumping the app " + r);
13659                    pw.flush();
13660                }
13661            }
13662        }
13663    }
13664
13665    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13666        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13667        if (procs == null) {
13668            pw.println("No process found for: " + args[0]);
13669            return;
13670        }
13671
13672        pw.println("Applications Database Info:");
13673
13674        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13675            ProcessRecord r = procs.get(i);
13676            if (r.thread != null) {
13677                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13678                pw.flush();
13679                try {
13680                    TransferPipe tp = new TransferPipe();
13681                    try {
13682                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13683                        tp.go(fd);
13684                    } finally {
13685                        tp.kill();
13686                    }
13687                } catch (IOException e) {
13688                    pw.println("Failure while dumping the app: " + r);
13689                    pw.flush();
13690                } catch (RemoteException e) {
13691                    pw.println("Got a RemoteException while dumping the app " + r);
13692                    pw.flush();
13693                }
13694            }
13695        }
13696    }
13697
13698    final static class MemItem {
13699        final boolean isProc;
13700        final String label;
13701        final String shortLabel;
13702        final long pss;
13703        final int id;
13704        final boolean hasActivities;
13705        ArrayList<MemItem> subitems;
13706
13707        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13708                boolean _hasActivities) {
13709            isProc = true;
13710            label = _label;
13711            shortLabel = _shortLabel;
13712            pss = _pss;
13713            id = _id;
13714            hasActivities = _hasActivities;
13715        }
13716
13717        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13718            isProc = false;
13719            label = _label;
13720            shortLabel = _shortLabel;
13721            pss = _pss;
13722            id = _id;
13723            hasActivities = false;
13724        }
13725    }
13726
13727    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13728            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13729        if (sort && !isCompact) {
13730            Collections.sort(items, new Comparator<MemItem>() {
13731                @Override
13732                public int compare(MemItem lhs, MemItem rhs) {
13733                    if (lhs.pss < rhs.pss) {
13734                        return 1;
13735                    } else if (lhs.pss > rhs.pss) {
13736                        return -1;
13737                    }
13738                    return 0;
13739                }
13740            });
13741        }
13742
13743        for (int i=0; i<items.size(); i++) {
13744            MemItem mi = items.get(i);
13745            if (!isCompact) {
13746                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13747            } else if (mi.isProc) {
13748                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13749                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13750                pw.println(mi.hasActivities ? ",a" : ",e");
13751            } else {
13752                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13753                pw.println(mi.pss);
13754            }
13755            if (mi.subitems != null) {
13756                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13757                        true, isCompact);
13758            }
13759        }
13760    }
13761
13762    // These are in KB.
13763    static final long[] DUMP_MEM_BUCKETS = new long[] {
13764        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13765        120*1024, 160*1024, 200*1024,
13766        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13767        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13768    };
13769
13770    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13771            boolean stackLike) {
13772        int start = label.lastIndexOf('.');
13773        if (start >= 0) start++;
13774        else start = 0;
13775        int end = label.length();
13776        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13777            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13778                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13779                out.append(bucket);
13780                out.append(stackLike ? "MB." : "MB ");
13781                out.append(label, start, end);
13782                return;
13783            }
13784        }
13785        out.append(memKB/1024);
13786        out.append(stackLike ? "MB." : "MB ");
13787        out.append(label, start, end);
13788    }
13789
13790    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13791            ProcessList.NATIVE_ADJ,
13792            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13793            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13794            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13795            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13796            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13797            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13798    };
13799    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13800            "Native",
13801            "System", "Persistent", "Persistent Service", "Foreground",
13802            "Visible", "Perceptible",
13803            "Heavy Weight", "Backup",
13804            "A Services", "Home",
13805            "Previous", "B Services", "Cached"
13806    };
13807    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13808            "native",
13809            "sys", "pers", "persvc", "fore",
13810            "vis", "percept",
13811            "heavy", "backup",
13812            "servicea", "home",
13813            "prev", "serviceb", "cached"
13814    };
13815
13816    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13817            long realtime, boolean isCheckinRequest, boolean isCompact) {
13818        if (isCheckinRequest || isCompact) {
13819            // short checkin version
13820            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13821        } else {
13822            pw.println("Applications Memory Usage (kB):");
13823            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13824        }
13825    }
13826
13827    private static final int KSM_SHARED = 0;
13828    private static final int KSM_SHARING = 1;
13829    private static final int KSM_UNSHARED = 2;
13830    private static final int KSM_VOLATILE = 3;
13831
13832    private final long[] getKsmInfo() {
13833        long[] longOut = new long[4];
13834        final int[] SINGLE_LONG_FORMAT = new int[] {
13835            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13836        };
13837        long[] longTmp = new long[1];
13838        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13839                SINGLE_LONG_FORMAT, null, longTmp, null);
13840        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13841        longTmp[0] = 0;
13842        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13843                SINGLE_LONG_FORMAT, null, longTmp, null);
13844        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13845        longTmp[0] = 0;
13846        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13847                SINGLE_LONG_FORMAT, null, longTmp, null);
13848        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13849        longTmp[0] = 0;
13850        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13851                SINGLE_LONG_FORMAT, null, longTmp, null);
13852        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13853        return longOut;
13854    }
13855
13856    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13857            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13858        boolean dumpDetails = false;
13859        boolean dumpFullDetails = false;
13860        boolean dumpDalvik = false;
13861        boolean oomOnly = false;
13862        boolean isCompact = false;
13863        boolean localOnly = false;
13864        boolean packages = false;
13865
13866        int opti = 0;
13867        while (opti < args.length) {
13868            String opt = args[opti];
13869            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13870                break;
13871            }
13872            opti++;
13873            if ("-a".equals(opt)) {
13874                dumpDetails = true;
13875                dumpFullDetails = true;
13876                dumpDalvik = true;
13877            } else if ("-d".equals(opt)) {
13878                dumpDalvik = true;
13879            } else if ("-c".equals(opt)) {
13880                isCompact = true;
13881            } else if ("--oom".equals(opt)) {
13882                oomOnly = true;
13883            } else if ("--local".equals(opt)) {
13884                localOnly = true;
13885            } else if ("--package".equals(opt)) {
13886                packages = true;
13887            } else if ("-h".equals(opt)) {
13888                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13889                pw.println("  -a: include all available information for each process.");
13890                pw.println("  -d: include dalvik details when dumping process details.");
13891                pw.println("  -c: dump in a compact machine-parseable representation.");
13892                pw.println("  --oom: only show processes organized by oom adj.");
13893                pw.println("  --local: only collect details locally, don't call process.");
13894                pw.println("  --package: interpret process arg as package, dumping all");
13895                pw.println("             processes that have loaded that package.");
13896                pw.println("If [process] is specified it can be the name or ");
13897                pw.println("pid of a specific process to dump.");
13898                return;
13899            } else {
13900                pw.println("Unknown argument: " + opt + "; use -h for help");
13901            }
13902        }
13903
13904        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13905        long uptime = SystemClock.uptimeMillis();
13906        long realtime = SystemClock.elapsedRealtime();
13907        final long[] tmpLong = new long[1];
13908
13909        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13910        if (procs == null) {
13911            // No Java processes.  Maybe they want to print a native process.
13912            if (args != null && args.length > opti
13913                    && args[opti].charAt(0) != '-') {
13914                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13915                        = new ArrayList<ProcessCpuTracker.Stats>();
13916                updateCpuStatsNow();
13917                int findPid = -1;
13918                try {
13919                    findPid = Integer.parseInt(args[opti]);
13920                } catch (NumberFormatException e) {
13921                }
13922                synchronized (mProcessCpuTracker) {
13923                    final int N = mProcessCpuTracker.countStats();
13924                    for (int i=0; i<N; i++) {
13925                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13926                        if (st.pid == findPid || (st.baseName != null
13927                                && st.baseName.equals(args[opti]))) {
13928                            nativeProcs.add(st);
13929                        }
13930                    }
13931                }
13932                if (nativeProcs.size() > 0) {
13933                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13934                            isCompact);
13935                    Debug.MemoryInfo mi = null;
13936                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13937                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13938                        final int pid = r.pid;
13939                        if (!isCheckinRequest && dumpDetails) {
13940                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13941                        }
13942                        if (mi == null) {
13943                            mi = new Debug.MemoryInfo();
13944                        }
13945                        if (dumpDetails || (!brief && !oomOnly)) {
13946                            Debug.getMemoryInfo(pid, mi);
13947                        } else {
13948                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13949                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13950                        }
13951                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13952                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13953                        if (isCheckinRequest) {
13954                            pw.println();
13955                        }
13956                    }
13957                    return;
13958                }
13959            }
13960            pw.println("No process found for: " + args[opti]);
13961            return;
13962        }
13963
13964        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13965            dumpDetails = true;
13966        }
13967
13968        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13969
13970        String[] innerArgs = new String[args.length-opti];
13971        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13972
13973        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13974        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13975        long nativePss = 0;
13976        long dalvikPss = 0;
13977        long otherPss = 0;
13978        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13979
13980        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13981        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13982                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13983
13984        long totalPss = 0;
13985        long cachedPss = 0;
13986
13987        Debug.MemoryInfo mi = null;
13988        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13989            final ProcessRecord r = procs.get(i);
13990            final IApplicationThread thread;
13991            final int pid;
13992            final int oomAdj;
13993            final boolean hasActivities;
13994            synchronized (this) {
13995                thread = r.thread;
13996                pid = r.pid;
13997                oomAdj = r.getSetAdjWithServices();
13998                hasActivities = r.activities.size() > 0;
13999            }
14000            if (thread != null) {
14001                if (!isCheckinRequest && dumpDetails) {
14002                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14003                }
14004                if (mi == null) {
14005                    mi = new Debug.MemoryInfo();
14006                }
14007                if (dumpDetails || (!brief && !oomOnly)) {
14008                    Debug.getMemoryInfo(pid, mi);
14009                } else {
14010                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14011                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14012                }
14013                if (dumpDetails) {
14014                    if (localOnly) {
14015                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14016                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14017                        if (isCheckinRequest) {
14018                            pw.println();
14019                        }
14020                    } else {
14021                        try {
14022                            pw.flush();
14023                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14024                                    dumpDalvik, innerArgs);
14025                        } catch (RemoteException e) {
14026                            if (!isCheckinRequest) {
14027                                pw.println("Got RemoteException!");
14028                                pw.flush();
14029                            }
14030                        }
14031                    }
14032                }
14033
14034                final long myTotalPss = mi.getTotalPss();
14035                final long myTotalUss = mi.getTotalUss();
14036
14037                synchronized (this) {
14038                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14039                        // Record this for posterity if the process has been stable.
14040                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14041                    }
14042                }
14043
14044                if (!isCheckinRequest && mi != null) {
14045                    totalPss += myTotalPss;
14046                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14047                            (hasActivities ? " / activities)" : ")"),
14048                            r.processName, myTotalPss, pid, hasActivities);
14049                    procMems.add(pssItem);
14050                    procMemsMap.put(pid, pssItem);
14051
14052                    nativePss += mi.nativePss;
14053                    dalvikPss += mi.dalvikPss;
14054                    otherPss += mi.otherPss;
14055                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14056                        long mem = mi.getOtherPss(j);
14057                        miscPss[j] += mem;
14058                        otherPss -= mem;
14059                    }
14060
14061                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14062                        cachedPss += myTotalPss;
14063                    }
14064
14065                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14066                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14067                                || oomIndex == (oomPss.length-1)) {
14068                            oomPss[oomIndex] += myTotalPss;
14069                            if (oomProcs[oomIndex] == null) {
14070                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14071                            }
14072                            oomProcs[oomIndex].add(pssItem);
14073                            break;
14074                        }
14075                    }
14076                }
14077            }
14078        }
14079
14080        long nativeProcTotalPss = 0;
14081
14082        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14083            // If we are showing aggregations, also look for native processes to
14084            // include so that our aggregations are more accurate.
14085            updateCpuStatsNow();
14086            synchronized (mProcessCpuTracker) {
14087                final int N = mProcessCpuTracker.countStats();
14088                for (int i=0; i<N; i++) {
14089                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14090                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14091                        if (mi == null) {
14092                            mi = new Debug.MemoryInfo();
14093                        }
14094                        if (!brief && !oomOnly) {
14095                            Debug.getMemoryInfo(st.pid, mi);
14096                        } else {
14097                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14098                            mi.nativePrivateDirty = (int)tmpLong[0];
14099                        }
14100
14101                        final long myTotalPss = mi.getTotalPss();
14102                        totalPss += myTotalPss;
14103                        nativeProcTotalPss += myTotalPss;
14104
14105                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14106                                st.name, myTotalPss, st.pid, false);
14107                        procMems.add(pssItem);
14108
14109                        nativePss += mi.nativePss;
14110                        dalvikPss += mi.dalvikPss;
14111                        otherPss += mi.otherPss;
14112                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14113                            long mem = mi.getOtherPss(j);
14114                            miscPss[j] += mem;
14115                            otherPss -= mem;
14116                        }
14117                        oomPss[0] += myTotalPss;
14118                        if (oomProcs[0] == null) {
14119                            oomProcs[0] = new ArrayList<MemItem>();
14120                        }
14121                        oomProcs[0].add(pssItem);
14122                    }
14123                }
14124            }
14125
14126            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14127
14128            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14129            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14130            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14131            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14132                String label = Debug.MemoryInfo.getOtherLabel(j);
14133                catMems.add(new MemItem(label, label, miscPss[j], j));
14134            }
14135
14136            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14137            for (int j=0; j<oomPss.length; j++) {
14138                if (oomPss[j] != 0) {
14139                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14140                            : DUMP_MEM_OOM_LABEL[j];
14141                    MemItem item = new MemItem(label, label, oomPss[j],
14142                            DUMP_MEM_OOM_ADJ[j]);
14143                    item.subitems = oomProcs[j];
14144                    oomMems.add(item);
14145                }
14146            }
14147
14148            if (!brief && !oomOnly && !isCompact) {
14149                pw.println();
14150                pw.println("Total PSS by process:");
14151                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14152                pw.println();
14153            }
14154            if (!isCompact) {
14155                pw.println("Total PSS by OOM adjustment:");
14156            }
14157            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14158            if (!brief && !oomOnly) {
14159                PrintWriter out = categoryPw != null ? categoryPw : pw;
14160                if (!isCompact) {
14161                    out.println();
14162                    out.println("Total PSS by category:");
14163                }
14164                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14165            }
14166            if (!isCompact) {
14167                pw.println();
14168            }
14169            MemInfoReader memInfo = new MemInfoReader();
14170            memInfo.readMemInfo();
14171            if (nativeProcTotalPss > 0) {
14172                synchronized (this) {
14173                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14174                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14175                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14176                }
14177            }
14178            if (!brief) {
14179                if (!isCompact) {
14180                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14181                    pw.print(" kB (status ");
14182                    switch (mLastMemoryLevel) {
14183                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14184                            pw.println("normal)");
14185                            break;
14186                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14187                            pw.println("moderate)");
14188                            break;
14189                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14190                            pw.println("low)");
14191                            break;
14192                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14193                            pw.println("critical)");
14194                            break;
14195                        default:
14196                            pw.print(mLastMemoryLevel);
14197                            pw.println(")");
14198                            break;
14199                    }
14200                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14201                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14202                            pw.print(cachedPss); pw.print(" cached pss + ");
14203                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14204                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14205                } else {
14206                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14207                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14208                            + memInfo.getFreeSizeKb()); pw.print(",");
14209                    pw.println(totalPss - cachedPss);
14210                }
14211            }
14212            if (!isCompact) {
14213                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14214                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14215                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14216                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14217                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14218                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14219                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14220            }
14221            if (!brief) {
14222                if (memInfo.getZramTotalSizeKb() != 0) {
14223                    if (!isCompact) {
14224                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14225                                pw.print(" kB physical used for ");
14226                                pw.print(memInfo.getSwapTotalSizeKb()
14227                                        - memInfo.getSwapFreeSizeKb());
14228                                pw.print(" kB in swap (");
14229                                pw.print(memInfo.getSwapTotalSizeKb());
14230                                pw.println(" kB total swap)");
14231                    } else {
14232                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14233                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14234                                pw.println(memInfo.getSwapFreeSizeKb());
14235                    }
14236                }
14237                final long[] ksm = getKsmInfo();
14238                if (!isCompact) {
14239                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14240                            || ksm[KSM_VOLATILE] != 0) {
14241                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14242                                pw.print(" kB saved from shared ");
14243                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14244                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14245                                pw.print(" kB unshared; ");
14246                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14247                    }
14248                    pw.print("   Tuning: ");
14249                    pw.print(ActivityManager.staticGetMemoryClass());
14250                    pw.print(" (large ");
14251                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14252                    pw.print("), oom ");
14253                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14254                    pw.print(" kB");
14255                    pw.print(", restore limit ");
14256                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14257                    pw.print(" kB");
14258                    if (ActivityManager.isLowRamDeviceStatic()) {
14259                        pw.print(" (low-ram)");
14260                    }
14261                    if (ActivityManager.isHighEndGfx()) {
14262                        pw.print(" (high-end-gfx)");
14263                    }
14264                    pw.println();
14265                } else {
14266                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14267                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14268                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14269                    pw.print("tuning,");
14270                    pw.print(ActivityManager.staticGetMemoryClass());
14271                    pw.print(',');
14272                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14273                    pw.print(',');
14274                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14275                    if (ActivityManager.isLowRamDeviceStatic()) {
14276                        pw.print(",low-ram");
14277                    }
14278                    if (ActivityManager.isHighEndGfx()) {
14279                        pw.print(",high-end-gfx");
14280                    }
14281                    pw.println();
14282                }
14283            }
14284        }
14285    }
14286
14287    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14288            String name) {
14289        sb.append("  ");
14290        sb.append(ProcessList.makeOomAdjString(oomAdj));
14291        sb.append(' ');
14292        sb.append(ProcessList.makeProcStateString(procState));
14293        sb.append(' ');
14294        ProcessList.appendRamKb(sb, pss);
14295        sb.append(" kB: ");
14296        sb.append(name);
14297    }
14298
14299    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14300        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14301        sb.append(" (");
14302        sb.append(mi.pid);
14303        sb.append(") ");
14304        sb.append(mi.adjType);
14305        sb.append('\n');
14306        if (mi.adjReason != null) {
14307            sb.append("                      ");
14308            sb.append(mi.adjReason);
14309            sb.append('\n');
14310        }
14311    }
14312
14313    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14314        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14315        for (int i=0, N=memInfos.size(); i<N; i++) {
14316            ProcessMemInfo mi = memInfos.get(i);
14317            infoMap.put(mi.pid, mi);
14318        }
14319        updateCpuStatsNow();
14320        synchronized (mProcessCpuTracker) {
14321            final int N = mProcessCpuTracker.countStats();
14322            for (int i=0; i<N; i++) {
14323                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14324                if (st.vsize > 0) {
14325                    long pss = Debug.getPss(st.pid, null);
14326                    if (pss > 0) {
14327                        if (infoMap.indexOfKey(st.pid) < 0) {
14328                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14329                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14330                            mi.pss = pss;
14331                            memInfos.add(mi);
14332                        }
14333                    }
14334                }
14335            }
14336        }
14337
14338        long totalPss = 0;
14339        for (int i=0, N=memInfos.size(); i<N; i++) {
14340            ProcessMemInfo mi = memInfos.get(i);
14341            if (mi.pss == 0) {
14342                mi.pss = Debug.getPss(mi.pid, null);
14343            }
14344            totalPss += mi.pss;
14345        }
14346        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14347            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14348                if (lhs.oomAdj != rhs.oomAdj) {
14349                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14350                }
14351                if (lhs.pss != rhs.pss) {
14352                    return lhs.pss < rhs.pss ? 1 : -1;
14353                }
14354                return 0;
14355            }
14356        });
14357
14358        StringBuilder tag = new StringBuilder(128);
14359        StringBuilder stack = new StringBuilder(128);
14360        tag.append("Low on memory -- ");
14361        appendMemBucket(tag, totalPss, "total", false);
14362        appendMemBucket(stack, totalPss, "total", true);
14363
14364        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14365        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14366        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14367
14368        boolean firstLine = true;
14369        int lastOomAdj = Integer.MIN_VALUE;
14370        long extraNativeRam = 0;
14371        long cachedPss = 0;
14372        for (int i=0, N=memInfos.size(); i<N; i++) {
14373            ProcessMemInfo mi = memInfos.get(i);
14374
14375            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14376                cachedPss += mi.pss;
14377            }
14378
14379            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14380                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14381                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14382                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14383                if (lastOomAdj != mi.oomAdj) {
14384                    lastOomAdj = mi.oomAdj;
14385                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14386                        tag.append(" / ");
14387                    }
14388                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14389                        if (firstLine) {
14390                            stack.append(":");
14391                            firstLine = false;
14392                        }
14393                        stack.append("\n\t at ");
14394                    } else {
14395                        stack.append("$");
14396                    }
14397                } else {
14398                    tag.append(" ");
14399                    stack.append("$");
14400                }
14401                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14402                    appendMemBucket(tag, mi.pss, mi.name, false);
14403                }
14404                appendMemBucket(stack, mi.pss, mi.name, true);
14405                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14406                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14407                    stack.append("(");
14408                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14409                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14410                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14411                            stack.append(":");
14412                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14413                        }
14414                    }
14415                    stack.append(")");
14416                }
14417            }
14418
14419            appendMemInfo(fullNativeBuilder, mi);
14420            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14421                // The short form only has native processes that are >= 1MB.
14422                if (mi.pss >= 1000) {
14423                    appendMemInfo(shortNativeBuilder, mi);
14424                } else {
14425                    extraNativeRam += mi.pss;
14426                }
14427            } else {
14428                // Short form has all other details, but if we have collected RAM
14429                // from smaller native processes let's dump a summary of that.
14430                if (extraNativeRam > 0) {
14431                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14432                            -1, extraNativeRam, "(Other native)");
14433                    shortNativeBuilder.append('\n');
14434                    extraNativeRam = 0;
14435                }
14436                appendMemInfo(fullJavaBuilder, mi);
14437            }
14438        }
14439
14440        fullJavaBuilder.append("           ");
14441        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14442        fullJavaBuilder.append(" kB: TOTAL\n");
14443
14444        MemInfoReader memInfo = new MemInfoReader();
14445        memInfo.readMemInfo();
14446        final long[] infos = memInfo.getRawInfo();
14447
14448        StringBuilder memInfoBuilder = new StringBuilder(1024);
14449        Debug.getMemInfo(infos);
14450        memInfoBuilder.append("  MemInfo: ");
14451        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14452        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14453        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14454        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14455        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14456        memInfoBuilder.append("           ");
14457        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14458        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14459        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14460        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14461        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14462            memInfoBuilder.append("  ZRAM: ");
14463            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14464            memInfoBuilder.append(" kB RAM, ");
14465            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14466            memInfoBuilder.append(" kB swap total, ");
14467            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14468            memInfoBuilder.append(" kB swap free\n");
14469        }
14470        final long[] ksm = getKsmInfo();
14471        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14472                || ksm[KSM_VOLATILE] != 0) {
14473            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14474            memInfoBuilder.append(" kB saved from shared ");
14475            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14476            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14477            memInfoBuilder.append(" kB unshared; ");
14478            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14479        }
14480        memInfoBuilder.append("  Free RAM: ");
14481        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14482                + memInfo.getFreeSizeKb());
14483        memInfoBuilder.append(" kB\n");
14484        memInfoBuilder.append("  Used RAM: ");
14485        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14486        memInfoBuilder.append(" kB\n");
14487        memInfoBuilder.append("  Lost RAM: ");
14488        memInfoBuilder.append(memInfo.getTotalSizeKb()
14489                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14490                - memInfo.getKernelUsedSizeKb());
14491        memInfoBuilder.append(" kB\n");
14492        Slog.i(TAG, "Low on memory:");
14493        Slog.i(TAG, shortNativeBuilder.toString());
14494        Slog.i(TAG, fullJavaBuilder.toString());
14495        Slog.i(TAG, memInfoBuilder.toString());
14496
14497        StringBuilder dropBuilder = new StringBuilder(1024);
14498        /*
14499        StringWriter oomSw = new StringWriter();
14500        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14501        StringWriter catSw = new StringWriter();
14502        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14503        String[] emptyArgs = new String[] { };
14504        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14505        oomPw.flush();
14506        String oomString = oomSw.toString();
14507        */
14508        dropBuilder.append("Low on memory:");
14509        dropBuilder.append(stack);
14510        dropBuilder.append('\n');
14511        dropBuilder.append(fullNativeBuilder);
14512        dropBuilder.append(fullJavaBuilder);
14513        dropBuilder.append('\n');
14514        dropBuilder.append(memInfoBuilder);
14515        dropBuilder.append('\n');
14516        /*
14517        dropBuilder.append(oomString);
14518        dropBuilder.append('\n');
14519        */
14520        StringWriter catSw = new StringWriter();
14521        synchronized (ActivityManagerService.this) {
14522            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14523            String[] emptyArgs = new String[] { };
14524            catPw.println();
14525            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14526            catPw.println();
14527            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14528                    false, false, null);
14529            catPw.println();
14530            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14531            catPw.flush();
14532        }
14533        dropBuilder.append(catSw.toString());
14534        addErrorToDropBox("lowmem", null, "system_server", null,
14535                null, tag.toString(), dropBuilder.toString(), null, null);
14536        //Slog.i(TAG, "Sent to dropbox:");
14537        //Slog.i(TAG, dropBuilder.toString());
14538        synchronized (ActivityManagerService.this) {
14539            long now = SystemClock.uptimeMillis();
14540            if (mLastMemUsageReportTime < now) {
14541                mLastMemUsageReportTime = now;
14542            }
14543        }
14544    }
14545
14546    /**
14547     * Searches array of arguments for the specified string
14548     * @param args array of argument strings
14549     * @param value value to search for
14550     * @return true if the value is contained in the array
14551     */
14552    private static boolean scanArgs(String[] args, String value) {
14553        if (args != null) {
14554            for (String arg : args) {
14555                if (value.equals(arg)) {
14556                    return true;
14557                }
14558            }
14559        }
14560        return false;
14561    }
14562
14563    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14564            ContentProviderRecord cpr, boolean always) {
14565        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14566
14567        if (!inLaunching || always) {
14568            synchronized (cpr) {
14569                cpr.launchingApp = null;
14570                cpr.notifyAll();
14571            }
14572            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14573            String names[] = cpr.info.authority.split(";");
14574            for (int j = 0; j < names.length; j++) {
14575                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14576            }
14577        }
14578
14579        for (int i=0; i<cpr.connections.size(); i++) {
14580            ContentProviderConnection conn = cpr.connections.get(i);
14581            if (conn.waiting) {
14582                // If this connection is waiting for the provider, then we don't
14583                // need to mess with its process unless we are always removing
14584                // or for some reason the provider is not currently launching.
14585                if (inLaunching && !always) {
14586                    continue;
14587                }
14588            }
14589            ProcessRecord capp = conn.client;
14590            conn.dead = true;
14591            if (conn.stableCount > 0) {
14592                if (!capp.persistent && capp.thread != null
14593                        && capp.pid != 0
14594                        && capp.pid != MY_PID) {
14595                    capp.kill("depends on provider "
14596                            + cpr.name.flattenToShortString()
14597                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14598                }
14599            } else if (capp.thread != null && conn.provider.provider != null) {
14600                try {
14601                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14602                } catch (RemoteException e) {
14603                }
14604                // In the protocol here, we don't expect the client to correctly
14605                // clean up this connection, we'll just remove it.
14606                cpr.connections.remove(i);
14607                conn.client.conProviders.remove(conn);
14608            }
14609        }
14610
14611        if (inLaunching && always) {
14612            mLaunchingProviders.remove(cpr);
14613        }
14614        return inLaunching;
14615    }
14616
14617    /**
14618     * Main code for cleaning up a process when it has gone away.  This is
14619     * called both as a result of the process dying, or directly when stopping
14620     * a process when running in single process mode.
14621     *
14622     * @return Returns true if the given process has been restarted, so the
14623     * app that was passed in must remain on the process lists.
14624     */
14625    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14626            boolean restarting, boolean allowRestart, int index) {
14627        if (index >= 0) {
14628            removeLruProcessLocked(app);
14629            ProcessList.remove(app.pid);
14630        }
14631
14632        mProcessesToGc.remove(app);
14633        mPendingPssProcesses.remove(app);
14634
14635        // Dismiss any open dialogs.
14636        if (app.crashDialog != null && !app.forceCrashReport) {
14637            app.crashDialog.dismiss();
14638            app.crashDialog = null;
14639        }
14640        if (app.anrDialog != null) {
14641            app.anrDialog.dismiss();
14642            app.anrDialog = null;
14643        }
14644        if (app.waitDialog != null) {
14645            app.waitDialog.dismiss();
14646            app.waitDialog = null;
14647        }
14648
14649        app.crashing = false;
14650        app.notResponding = false;
14651
14652        app.resetPackageList(mProcessStats);
14653        app.unlinkDeathRecipient();
14654        app.makeInactive(mProcessStats);
14655        app.waitingToKill = null;
14656        app.forcingToForeground = null;
14657        updateProcessForegroundLocked(app, false, false);
14658        app.foregroundActivities = false;
14659        app.hasShownUi = false;
14660        app.treatLikeActivity = false;
14661        app.hasAboveClient = false;
14662        app.hasClientActivities = false;
14663
14664        mServices.killServicesLocked(app, allowRestart);
14665
14666        boolean restart = false;
14667
14668        // Remove published content providers.
14669        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14670            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14671            final boolean always = app.bad || !allowRestart;
14672            if (removeDyingProviderLocked(app, cpr, always) || always) {
14673                // We left the provider in the launching list, need to
14674                // restart it.
14675                restart = true;
14676            }
14677
14678            cpr.provider = null;
14679            cpr.proc = null;
14680        }
14681        app.pubProviders.clear();
14682
14683        // Take care of any launching providers waiting for this process.
14684        if (checkAppInLaunchingProvidersLocked(app, false)) {
14685            restart = true;
14686        }
14687
14688        // Unregister from connected content providers.
14689        if (!app.conProviders.isEmpty()) {
14690            for (int i=0; i<app.conProviders.size(); i++) {
14691                ContentProviderConnection conn = app.conProviders.get(i);
14692                conn.provider.connections.remove(conn);
14693            }
14694            app.conProviders.clear();
14695        }
14696
14697        // At this point there may be remaining entries in mLaunchingProviders
14698        // where we were the only one waiting, so they are no longer of use.
14699        // Look for these and clean up if found.
14700        // XXX Commented out for now.  Trying to figure out a way to reproduce
14701        // the actual situation to identify what is actually going on.
14702        if (false) {
14703            for (int i=0; i<mLaunchingProviders.size(); i++) {
14704                ContentProviderRecord cpr = (ContentProviderRecord)
14705                        mLaunchingProviders.get(i);
14706                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14707                    synchronized (cpr) {
14708                        cpr.launchingApp = null;
14709                        cpr.notifyAll();
14710                    }
14711                }
14712            }
14713        }
14714
14715        skipCurrentReceiverLocked(app);
14716
14717        // Unregister any receivers.
14718        for (int i=app.receivers.size()-1; i>=0; i--) {
14719            removeReceiverLocked(app.receivers.valueAt(i));
14720        }
14721        app.receivers.clear();
14722
14723        // If the app is undergoing backup, tell the backup manager about it
14724        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14725            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14726                    + mBackupTarget.appInfo + " died during backup");
14727            try {
14728                IBackupManager bm = IBackupManager.Stub.asInterface(
14729                        ServiceManager.getService(Context.BACKUP_SERVICE));
14730                bm.agentDisconnected(app.info.packageName);
14731            } catch (RemoteException e) {
14732                // can't happen; backup manager is local
14733            }
14734        }
14735
14736        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14737            ProcessChangeItem item = mPendingProcessChanges.get(i);
14738            if (item.pid == app.pid) {
14739                mPendingProcessChanges.remove(i);
14740                mAvailProcessChanges.add(item);
14741            }
14742        }
14743        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14744
14745        // If the caller is restarting this app, then leave it in its
14746        // current lists and let the caller take care of it.
14747        if (restarting) {
14748            return false;
14749        }
14750
14751        if (!app.persistent || app.isolated) {
14752            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14753                    "Removing non-persistent process during cleanup: " + app);
14754            mProcessNames.remove(app.processName, app.uid);
14755            mIsolatedProcesses.remove(app.uid);
14756            if (mHeavyWeightProcess == app) {
14757                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14758                        mHeavyWeightProcess.userId, 0));
14759                mHeavyWeightProcess = null;
14760            }
14761        } else if (!app.removed) {
14762            // This app is persistent, so we need to keep its record around.
14763            // If it is not already on the pending app list, add it there
14764            // and start a new process for it.
14765            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14766                mPersistentStartingProcesses.add(app);
14767                restart = true;
14768            }
14769        }
14770        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14771                "Clean-up removing on hold: " + app);
14772        mProcessesOnHold.remove(app);
14773
14774        if (app == mHomeProcess) {
14775            mHomeProcess = null;
14776        }
14777        if (app == mPreviousProcess) {
14778            mPreviousProcess = null;
14779        }
14780
14781        if (restart && !app.isolated) {
14782            // We have components that still need to be running in the
14783            // process, so re-launch it.
14784            if (index < 0) {
14785                ProcessList.remove(app.pid);
14786            }
14787            mProcessNames.put(app.processName, app.uid, app);
14788            startProcessLocked(app, "restart", app.processName);
14789            return true;
14790        } else if (app.pid > 0 && app.pid != MY_PID) {
14791            // Goodbye!
14792            boolean removed;
14793            synchronized (mPidsSelfLocked) {
14794                mPidsSelfLocked.remove(app.pid);
14795                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14796            }
14797            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14798            if (app.isolated) {
14799                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14800            }
14801            app.setPid(0);
14802        }
14803        return false;
14804    }
14805
14806    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14807        // Look through the content providers we are waiting to have launched,
14808        // and if any run in this process then either schedule a restart of
14809        // the process or kill the client waiting for it if this process has
14810        // gone bad.
14811        int NL = mLaunchingProviders.size();
14812        boolean restart = false;
14813        for (int i=0; i<NL; i++) {
14814            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14815            if (cpr.launchingApp == app) {
14816                if (!alwaysBad && !app.bad) {
14817                    restart = true;
14818                } else {
14819                    removeDyingProviderLocked(app, cpr, true);
14820                    // cpr should have been removed from mLaunchingProviders
14821                    NL = mLaunchingProviders.size();
14822                    i--;
14823                }
14824            }
14825        }
14826        return restart;
14827    }
14828
14829    // =========================================================
14830    // SERVICES
14831    // =========================================================
14832
14833    @Override
14834    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14835            int flags) {
14836        enforceNotIsolatedCaller("getServices");
14837        synchronized (this) {
14838            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14839        }
14840    }
14841
14842    @Override
14843    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14844        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14845        synchronized (this) {
14846            return mServices.getRunningServiceControlPanelLocked(name);
14847        }
14848    }
14849
14850    @Override
14851    public ComponentName startService(IApplicationThread caller, Intent service,
14852            String resolvedType, int userId) {
14853        enforceNotIsolatedCaller("startService");
14854        // Refuse possible leaked file descriptors
14855        if (service != null && service.hasFileDescriptors() == true) {
14856            throw new IllegalArgumentException("File descriptors passed in Intent");
14857        }
14858
14859        if (DEBUG_SERVICE)
14860            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14861        synchronized(this) {
14862            final int callingPid = Binder.getCallingPid();
14863            final int callingUid = Binder.getCallingUid();
14864            final long origId = Binder.clearCallingIdentity();
14865            ComponentName res = mServices.startServiceLocked(caller, service,
14866                    resolvedType, callingPid, callingUid, userId);
14867            Binder.restoreCallingIdentity(origId);
14868            return res;
14869        }
14870    }
14871
14872    ComponentName startServiceInPackage(int uid,
14873            Intent service, String resolvedType, int userId) {
14874        synchronized(this) {
14875            if (DEBUG_SERVICE)
14876                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14877            final long origId = Binder.clearCallingIdentity();
14878            ComponentName res = mServices.startServiceLocked(null, service,
14879                    resolvedType, -1, uid, userId);
14880            Binder.restoreCallingIdentity(origId);
14881            return res;
14882        }
14883    }
14884
14885    @Override
14886    public int stopService(IApplicationThread caller, Intent service,
14887            String resolvedType, int userId) {
14888        enforceNotIsolatedCaller("stopService");
14889        // Refuse possible leaked file descriptors
14890        if (service != null && service.hasFileDescriptors() == true) {
14891            throw new IllegalArgumentException("File descriptors passed in Intent");
14892        }
14893
14894        synchronized(this) {
14895            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14896        }
14897    }
14898
14899    @Override
14900    public IBinder peekService(Intent service, String resolvedType) {
14901        enforceNotIsolatedCaller("peekService");
14902        // Refuse possible leaked file descriptors
14903        if (service != null && service.hasFileDescriptors() == true) {
14904            throw new IllegalArgumentException("File descriptors passed in Intent");
14905        }
14906        synchronized(this) {
14907            return mServices.peekServiceLocked(service, resolvedType);
14908        }
14909    }
14910
14911    @Override
14912    public boolean stopServiceToken(ComponentName className, IBinder token,
14913            int startId) {
14914        synchronized(this) {
14915            return mServices.stopServiceTokenLocked(className, token, startId);
14916        }
14917    }
14918
14919    @Override
14920    public void setServiceForeground(ComponentName className, IBinder token,
14921            int id, Notification notification, boolean removeNotification) {
14922        synchronized(this) {
14923            mServices.setServiceForegroundLocked(className, token, id, notification,
14924                    removeNotification);
14925        }
14926    }
14927
14928    @Override
14929    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14930            boolean requireFull, String name, String callerPackage) {
14931        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14932                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14933    }
14934
14935    int unsafeConvertIncomingUser(int userId) {
14936        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14937                ? mCurrentUserId : userId;
14938    }
14939
14940    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14941            int allowMode, String name, String callerPackage) {
14942        final int callingUserId = UserHandle.getUserId(callingUid);
14943        if (callingUserId == userId) {
14944            return userId;
14945        }
14946
14947        // Note that we may be accessing mCurrentUserId outside of a lock...
14948        // shouldn't be a big deal, if this is being called outside
14949        // of a locked context there is intrinsically a race with
14950        // the value the caller will receive and someone else changing it.
14951        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14952        // we will switch to the calling user if access to the current user fails.
14953        int targetUserId = unsafeConvertIncomingUser(userId);
14954
14955        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14956            final boolean allow;
14957            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14958                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14959                // If the caller has this permission, they always pass go.  And collect $200.
14960                allow = true;
14961            } else if (allowMode == ALLOW_FULL_ONLY) {
14962                // We require full access, sucks to be you.
14963                allow = false;
14964            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14965                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14966                // If the caller does not have either permission, they are always doomed.
14967                allow = false;
14968            } else if (allowMode == ALLOW_NON_FULL) {
14969                // We are blanket allowing non-full access, you lucky caller!
14970                allow = true;
14971            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14972                // We may or may not allow this depending on whether the two users are
14973                // in the same profile.
14974                synchronized (mUserProfileGroupIdsSelfLocked) {
14975                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14976                            UserInfo.NO_PROFILE_GROUP_ID);
14977                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14978                            UserInfo.NO_PROFILE_GROUP_ID);
14979                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14980                            && callingProfile == targetProfile;
14981                }
14982            } else {
14983                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14984            }
14985            if (!allow) {
14986                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14987                    // In this case, they would like to just execute as their
14988                    // owner user instead of failing.
14989                    targetUserId = callingUserId;
14990                } else {
14991                    StringBuilder builder = new StringBuilder(128);
14992                    builder.append("Permission Denial: ");
14993                    builder.append(name);
14994                    if (callerPackage != null) {
14995                        builder.append(" from ");
14996                        builder.append(callerPackage);
14997                    }
14998                    builder.append(" asks to run as user ");
14999                    builder.append(userId);
15000                    builder.append(" but is calling from user ");
15001                    builder.append(UserHandle.getUserId(callingUid));
15002                    builder.append("; this requires ");
15003                    builder.append(INTERACT_ACROSS_USERS_FULL);
15004                    if (allowMode != ALLOW_FULL_ONLY) {
15005                        builder.append(" or ");
15006                        builder.append(INTERACT_ACROSS_USERS);
15007                    }
15008                    String msg = builder.toString();
15009                    Slog.w(TAG, msg);
15010                    throw new SecurityException(msg);
15011                }
15012            }
15013        }
15014        if (!allowAll && targetUserId < 0) {
15015            throw new IllegalArgumentException(
15016                    "Call does not support special user #" + targetUserId);
15017        }
15018        // Check shell permission
15019        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15020            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15021                    targetUserId)) {
15022                throw new SecurityException("Shell does not have permission to access user "
15023                        + targetUserId + "\n " + Debug.getCallers(3));
15024            }
15025        }
15026        return targetUserId;
15027    }
15028
15029    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15030            String className, int flags) {
15031        boolean result = false;
15032        // For apps that don't have pre-defined UIDs, check for permission
15033        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15034            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15035                if (ActivityManager.checkUidPermission(
15036                        INTERACT_ACROSS_USERS,
15037                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15038                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15039                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15040                            + " requests FLAG_SINGLE_USER, but app does not hold "
15041                            + INTERACT_ACROSS_USERS;
15042                    Slog.w(TAG, msg);
15043                    throw new SecurityException(msg);
15044                }
15045                // Permission passed
15046                result = true;
15047            }
15048        } else if ("system".equals(componentProcessName)) {
15049            result = true;
15050        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15051            // Phone app and persistent apps are allowed to export singleuser providers.
15052            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15053                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15054        }
15055        if (DEBUG_MU) {
15056            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15057                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15058        }
15059        return result;
15060    }
15061
15062    /**
15063     * Checks to see if the caller is in the same app as the singleton
15064     * component, or the component is in a special app. It allows special apps
15065     * to export singleton components but prevents exporting singleton
15066     * components for regular apps.
15067     */
15068    boolean isValidSingletonCall(int callingUid, int componentUid) {
15069        int componentAppId = UserHandle.getAppId(componentUid);
15070        return UserHandle.isSameApp(callingUid, componentUid)
15071                || componentAppId == Process.SYSTEM_UID
15072                || componentAppId == Process.PHONE_UID
15073                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15074                        == PackageManager.PERMISSION_GRANTED;
15075    }
15076
15077    public int bindService(IApplicationThread caller, IBinder token,
15078            Intent service, String resolvedType,
15079            IServiceConnection connection, int flags, int userId) {
15080        enforceNotIsolatedCaller("bindService");
15081
15082        // Refuse possible leaked file descriptors
15083        if (service != null && service.hasFileDescriptors() == true) {
15084            throw new IllegalArgumentException("File descriptors passed in Intent");
15085        }
15086
15087        synchronized(this) {
15088            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15089                    connection, flags, userId);
15090        }
15091    }
15092
15093    public boolean unbindService(IServiceConnection connection) {
15094        synchronized (this) {
15095            return mServices.unbindServiceLocked(connection);
15096        }
15097    }
15098
15099    public void publishService(IBinder token, Intent intent, IBinder service) {
15100        // Refuse possible leaked file descriptors
15101        if (intent != null && intent.hasFileDescriptors() == true) {
15102            throw new IllegalArgumentException("File descriptors passed in Intent");
15103        }
15104
15105        synchronized(this) {
15106            if (!(token instanceof ServiceRecord)) {
15107                throw new IllegalArgumentException("Invalid service token");
15108            }
15109            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15110        }
15111    }
15112
15113    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15114        // Refuse possible leaked file descriptors
15115        if (intent != null && intent.hasFileDescriptors() == true) {
15116            throw new IllegalArgumentException("File descriptors passed in Intent");
15117        }
15118
15119        synchronized(this) {
15120            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15121        }
15122    }
15123
15124    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15125        synchronized(this) {
15126            if (!(token instanceof ServiceRecord)) {
15127                throw new IllegalArgumentException("Invalid service token");
15128            }
15129            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15130        }
15131    }
15132
15133    // =========================================================
15134    // BACKUP AND RESTORE
15135    // =========================================================
15136
15137    // Cause the target app to be launched if necessary and its backup agent
15138    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15139    // activity manager to announce its creation.
15140    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15141        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15142        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15143
15144        synchronized(this) {
15145            // !!! TODO: currently no check here that we're already bound
15146            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15147            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15148            synchronized (stats) {
15149                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15150            }
15151
15152            // Backup agent is now in use, its package can't be stopped.
15153            try {
15154                AppGlobals.getPackageManager().setPackageStoppedState(
15155                        app.packageName, false, UserHandle.getUserId(app.uid));
15156            } catch (RemoteException e) {
15157            } catch (IllegalArgumentException e) {
15158                Slog.w(TAG, "Failed trying to unstop package "
15159                        + app.packageName + ": " + e);
15160            }
15161
15162            BackupRecord r = new BackupRecord(ss, app, backupMode);
15163            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15164                    ? new ComponentName(app.packageName, app.backupAgentName)
15165                    : new ComponentName("android", "FullBackupAgent");
15166            // startProcessLocked() returns existing proc's record if it's already running
15167            ProcessRecord proc = startProcessLocked(app.processName, app,
15168                    false, 0, "backup", hostingName, false, false, false);
15169            if (proc == null) {
15170                Slog.e(TAG, "Unable to start backup agent process " + r);
15171                return false;
15172            }
15173
15174            r.app = proc;
15175            mBackupTarget = r;
15176            mBackupAppName = app.packageName;
15177
15178            // Try not to kill the process during backup
15179            updateOomAdjLocked(proc);
15180
15181            // If the process is already attached, schedule the creation of the backup agent now.
15182            // If it is not yet live, this will be done when it attaches to the framework.
15183            if (proc.thread != null) {
15184                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15185                try {
15186                    proc.thread.scheduleCreateBackupAgent(app,
15187                            compatibilityInfoForPackageLocked(app), backupMode);
15188                } catch (RemoteException e) {
15189                    // Will time out on the backup manager side
15190                }
15191            } else {
15192                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15193            }
15194            // Invariants: at this point, the target app process exists and the application
15195            // is either already running or in the process of coming up.  mBackupTarget and
15196            // mBackupAppName describe the app, so that when it binds back to the AM we
15197            // know that it's scheduled for a backup-agent operation.
15198        }
15199
15200        return true;
15201    }
15202
15203    @Override
15204    public void clearPendingBackup() {
15205        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15206        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15207
15208        synchronized (this) {
15209            mBackupTarget = null;
15210            mBackupAppName = null;
15211        }
15212    }
15213
15214    // A backup agent has just come up
15215    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15216        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15217                + " = " + agent);
15218
15219        synchronized(this) {
15220            if (!agentPackageName.equals(mBackupAppName)) {
15221                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15222                return;
15223            }
15224        }
15225
15226        long oldIdent = Binder.clearCallingIdentity();
15227        try {
15228            IBackupManager bm = IBackupManager.Stub.asInterface(
15229                    ServiceManager.getService(Context.BACKUP_SERVICE));
15230            bm.agentConnected(agentPackageName, agent);
15231        } catch (RemoteException e) {
15232            // can't happen; the backup manager service is local
15233        } catch (Exception e) {
15234            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15235            e.printStackTrace();
15236        } finally {
15237            Binder.restoreCallingIdentity(oldIdent);
15238        }
15239    }
15240
15241    // done with this agent
15242    public void unbindBackupAgent(ApplicationInfo appInfo) {
15243        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15244        if (appInfo == null) {
15245            Slog.w(TAG, "unbind backup agent for null app");
15246            return;
15247        }
15248
15249        synchronized(this) {
15250            try {
15251                if (mBackupAppName == null) {
15252                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15253                    return;
15254                }
15255
15256                if (!mBackupAppName.equals(appInfo.packageName)) {
15257                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15258                    return;
15259                }
15260
15261                // Not backing this app up any more; reset its OOM adjustment
15262                final ProcessRecord proc = mBackupTarget.app;
15263                updateOomAdjLocked(proc);
15264
15265                // If the app crashed during backup, 'thread' will be null here
15266                if (proc.thread != null) {
15267                    try {
15268                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15269                                compatibilityInfoForPackageLocked(appInfo));
15270                    } catch (Exception e) {
15271                        Slog.e(TAG, "Exception when unbinding backup agent:");
15272                        e.printStackTrace();
15273                    }
15274                }
15275            } finally {
15276                mBackupTarget = null;
15277                mBackupAppName = null;
15278            }
15279        }
15280    }
15281    // =========================================================
15282    // BROADCASTS
15283    // =========================================================
15284
15285    private final List getStickiesLocked(String action, IntentFilter filter,
15286            List cur, int userId) {
15287        final ContentResolver resolver = mContext.getContentResolver();
15288        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15289        if (stickies == null) {
15290            return cur;
15291        }
15292        final ArrayList<Intent> list = stickies.get(action);
15293        if (list == null) {
15294            return cur;
15295        }
15296        int N = list.size();
15297        for (int i=0; i<N; i++) {
15298            Intent intent = list.get(i);
15299            if (filter.match(resolver, intent, true, TAG) >= 0) {
15300                if (cur == null) {
15301                    cur = new ArrayList<Intent>();
15302                }
15303                cur.add(intent);
15304            }
15305        }
15306        return cur;
15307    }
15308
15309    boolean isPendingBroadcastProcessLocked(int pid) {
15310        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15311                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15312    }
15313
15314    void skipPendingBroadcastLocked(int pid) {
15315            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15316            for (BroadcastQueue queue : mBroadcastQueues) {
15317                queue.skipPendingBroadcastLocked(pid);
15318            }
15319    }
15320
15321    // The app just attached; send any pending broadcasts that it should receive
15322    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15323        boolean didSomething = false;
15324        for (BroadcastQueue queue : mBroadcastQueues) {
15325            didSomething |= queue.sendPendingBroadcastsLocked(app);
15326        }
15327        return didSomething;
15328    }
15329
15330    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15331            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15332        enforceNotIsolatedCaller("registerReceiver");
15333        int callingUid;
15334        int callingPid;
15335        synchronized(this) {
15336            ProcessRecord callerApp = null;
15337            if (caller != null) {
15338                callerApp = getRecordForAppLocked(caller);
15339                if (callerApp == null) {
15340                    throw new SecurityException(
15341                            "Unable to find app for caller " + caller
15342                            + " (pid=" + Binder.getCallingPid()
15343                            + ") when registering receiver " + receiver);
15344                }
15345                if (callerApp.info.uid != Process.SYSTEM_UID &&
15346                        !callerApp.pkgList.containsKey(callerPackage) &&
15347                        !"android".equals(callerPackage)) {
15348                    throw new SecurityException("Given caller package " + callerPackage
15349                            + " is not running in process " + callerApp);
15350                }
15351                callingUid = callerApp.info.uid;
15352                callingPid = callerApp.pid;
15353            } else {
15354                callerPackage = null;
15355                callingUid = Binder.getCallingUid();
15356                callingPid = Binder.getCallingPid();
15357            }
15358
15359            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15360                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15361
15362            List allSticky = null;
15363
15364            // Look for any matching sticky broadcasts...
15365            Iterator actions = filter.actionsIterator();
15366            if (actions != null) {
15367                while (actions.hasNext()) {
15368                    String action = (String)actions.next();
15369                    allSticky = getStickiesLocked(action, filter, allSticky,
15370                            UserHandle.USER_ALL);
15371                    allSticky = getStickiesLocked(action, filter, allSticky,
15372                            UserHandle.getUserId(callingUid));
15373                }
15374            } else {
15375                allSticky = getStickiesLocked(null, filter, allSticky,
15376                        UserHandle.USER_ALL);
15377                allSticky = getStickiesLocked(null, filter, allSticky,
15378                        UserHandle.getUserId(callingUid));
15379            }
15380
15381            // The first sticky in the list is returned directly back to
15382            // the client.
15383            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15384
15385            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15386                    + ": " + sticky);
15387
15388            if (receiver == null) {
15389                return sticky;
15390            }
15391
15392            ReceiverList rl
15393                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15394            if (rl == null) {
15395                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15396                        userId, receiver);
15397                if (rl.app != null) {
15398                    rl.app.receivers.add(rl);
15399                } else {
15400                    try {
15401                        receiver.asBinder().linkToDeath(rl, 0);
15402                    } catch (RemoteException e) {
15403                        return sticky;
15404                    }
15405                    rl.linkedToDeath = true;
15406                }
15407                mRegisteredReceivers.put(receiver.asBinder(), rl);
15408            } else if (rl.uid != callingUid) {
15409                throw new IllegalArgumentException(
15410                        "Receiver requested to register for uid " + callingUid
15411                        + " was previously registered for uid " + rl.uid);
15412            } else if (rl.pid != callingPid) {
15413                throw new IllegalArgumentException(
15414                        "Receiver requested to register for pid " + callingPid
15415                        + " was previously registered for pid " + rl.pid);
15416            } else if (rl.userId != userId) {
15417                throw new IllegalArgumentException(
15418                        "Receiver requested to register for user " + userId
15419                        + " was previously registered for user " + rl.userId);
15420            }
15421            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15422                    permission, callingUid, userId);
15423            rl.add(bf);
15424            if (!bf.debugCheck()) {
15425                Slog.w(TAG, "==> For Dynamic broadast");
15426            }
15427            mReceiverResolver.addFilter(bf);
15428
15429            // Enqueue broadcasts for all existing stickies that match
15430            // this filter.
15431            if (allSticky != null) {
15432                ArrayList receivers = new ArrayList();
15433                receivers.add(bf);
15434
15435                int N = allSticky.size();
15436                for (int i=0; i<N; i++) {
15437                    Intent intent = (Intent)allSticky.get(i);
15438                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15439                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15440                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15441                            null, null, false, true, true, -1);
15442                    queue.enqueueParallelBroadcastLocked(r);
15443                    queue.scheduleBroadcastsLocked();
15444                }
15445            }
15446
15447            return sticky;
15448        }
15449    }
15450
15451    public void unregisterReceiver(IIntentReceiver receiver) {
15452        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15453
15454        final long origId = Binder.clearCallingIdentity();
15455        try {
15456            boolean doTrim = false;
15457
15458            synchronized(this) {
15459                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15460                if (rl != null) {
15461                    if (rl.curBroadcast != null) {
15462                        BroadcastRecord r = rl.curBroadcast;
15463                        final boolean doNext = finishReceiverLocked(
15464                                receiver.asBinder(), r.resultCode, r.resultData,
15465                                r.resultExtras, r.resultAbort);
15466                        if (doNext) {
15467                            doTrim = true;
15468                            r.queue.processNextBroadcast(false);
15469                        }
15470                    }
15471
15472                    if (rl.app != null) {
15473                        rl.app.receivers.remove(rl);
15474                    }
15475                    removeReceiverLocked(rl);
15476                    if (rl.linkedToDeath) {
15477                        rl.linkedToDeath = false;
15478                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15479                    }
15480                }
15481            }
15482
15483            // If we actually concluded any broadcasts, we might now be able
15484            // to trim the recipients' apps from our working set
15485            if (doTrim) {
15486                trimApplications();
15487                return;
15488            }
15489
15490        } finally {
15491            Binder.restoreCallingIdentity(origId);
15492        }
15493    }
15494
15495    void removeReceiverLocked(ReceiverList rl) {
15496        mRegisteredReceivers.remove(rl.receiver.asBinder());
15497        int N = rl.size();
15498        for (int i=0; i<N; i++) {
15499            mReceiverResolver.removeFilter(rl.get(i));
15500        }
15501    }
15502
15503    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15504        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15505            ProcessRecord r = mLruProcesses.get(i);
15506            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15507                try {
15508                    r.thread.dispatchPackageBroadcast(cmd, packages);
15509                } catch (RemoteException ex) {
15510                }
15511            }
15512        }
15513    }
15514
15515    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15516            int callingUid, int[] users) {
15517        List<ResolveInfo> receivers = null;
15518        try {
15519            HashSet<ComponentName> singleUserReceivers = null;
15520            boolean scannedFirstReceivers = false;
15521            for (int user : users) {
15522                // Skip users that have Shell restrictions
15523                if (callingUid == Process.SHELL_UID
15524                        && getUserManagerLocked().hasUserRestriction(
15525                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15526                    continue;
15527                }
15528                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15529                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15530                if (user != 0 && newReceivers != null) {
15531                    // If this is not the primary user, we need to check for
15532                    // any receivers that should be filtered out.
15533                    for (int i=0; i<newReceivers.size(); i++) {
15534                        ResolveInfo ri = newReceivers.get(i);
15535                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15536                            newReceivers.remove(i);
15537                            i--;
15538                        }
15539                    }
15540                }
15541                if (newReceivers != null && newReceivers.size() == 0) {
15542                    newReceivers = null;
15543                }
15544                if (receivers == null) {
15545                    receivers = newReceivers;
15546                } else if (newReceivers != null) {
15547                    // We need to concatenate the additional receivers
15548                    // found with what we have do far.  This would be easy,
15549                    // but we also need to de-dup any receivers that are
15550                    // singleUser.
15551                    if (!scannedFirstReceivers) {
15552                        // Collect any single user receivers we had already retrieved.
15553                        scannedFirstReceivers = true;
15554                        for (int i=0; i<receivers.size(); i++) {
15555                            ResolveInfo ri = receivers.get(i);
15556                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15557                                ComponentName cn = new ComponentName(
15558                                        ri.activityInfo.packageName, ri.activityInfo.name);
15559                                if (singleUserReceivers == null) {
15560                                    singleUserReceivers = new HashSet<ComponentName>();
15561                                }
15562                                singleUserReceivers.add(cn);
15563                            }
15564                        }
15565                    }
15566                    // Add the new results to the existing results, tracking
15567                    // and de-dupping single user receivers.
15568                    for (int i=0; i<newReceivers.size(); i++) {
15569                        ResolveInfo ri = newReceivers.get(i);
15570                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15571                            ComponentName cn = new ComponentName(
15572                                    ri.activityInfo.packageName, ri.activityInfo.name);
15573                            if (singleUserReceivers == null) {
15574                                singleUserReceivers = new HashSet<ComponentName>();
15575                            }
15576                            if (!singleUserReceivers.contains(cn)) {
15577                                singleUserReceivers.add(cn);
15578                                receivers.add(ri);
15579                            }
15580                        } else {
15581                            receivers.add(ri);
15582                        }
15583                    }
15584                }
15585            }
15586        } catch (RemoteException ex) {
15587            // pm is in same process, this will never happen.
15588        }
15589        return receivers;
15590    }
15591
15592    private final int broadcastIntentLocked(ProcessRecord callerApp,
15593            String callerPackage, Intent intent, String resolvedType,
15594            IIntentReceiver resultTo, int resultCode, String resultData,
15595            Bundle map, String requiredPermission, int appOp,
15596            boolean ordered, boolean sticky, int callingPid, int callingUid,
15597            int userId) {
15598        intent = new Intent(intent);
15599
15600        // By default broadcasts do not go to stopped apps.
15601        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15602
15603        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15604            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15605            + " ordered=" + ordered + " userid=" + userId);
15606        if ((resultTo != null) && !ordered) {
15607            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15608        }
15609
15610        userId = handleIncomingUser(callingPid, callingUid, userId,
15611                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15612
15613        // Make sure that the user who is receiving this broadcast is started.
15614        // If not, we will just skip it.
15615
15616        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15617            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15618                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15619                Slog.w(TAG, "Skipping broadcast of " + intent
15620                        + ": user " + userId + " is stopped");
15621                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15622            }
15623        }
15624
15625        /*
15626         * Prevent non-system code (defined here to be non-persistent
15627         * processes) from sending protected broadcasts.
15628         */
15629        int callingAppId = UserHandle.getAppId(callingUid);
15630        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15631            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15632            || callingAppId == Process.NFC_UID || callingUid == 0) {
15633            // Always okay.
15634        } else if (callerApp == null || !callerApp.persistent) {
15635            try {
15636                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15637                        intent.getAction())) {
15638                    String msg = "Permission Denial: not allowed to send broadcast "
15639                            + intent.getAction() + " from pid="
15640                            + callingPid + ", uid=" + callingUid;
15641                    Slog.w(TAG, msg);
15642                    throw new SecurityException(msg);
15643                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15644                    // Special case for compatibility: we don't want apps to send this,
15645                    // but historically it has not been protected and apps may be using it
15646                    // to poke their own app widget.  So, instead of making it protected,
15647                    // just limit it to the caller.
15648                    if (callerApp == null) {
15649                        String msg = "Permission Denial: not allowed to send broadcast "
15650                                + intent.getAction() + " from unknown caller.";
15651                        Slog.w(TAG, msg);
15652                        throw new SecurityException(msg);
15653                    } else if (intent.getComponent() != null) {
15654                        // They are good enough to send to an explicit component...  verify
15655                        // it is being sent to the calling app.
15656                        if (!intent.getComponent().getPackageName().equals(
15657                                callerApp.info.packageName)) {
15658                            String msg = "Permission Denial: not allowed to send broadcast "
15659                                    + intent.getAction() + " to "
15660                                    + intent.getComponent().getPackageName() + " from "
15661                                    + callerApp.info.packageName;
15662                            Slog.w(TAG, msg);
15663                            throw new SecurityException(msg);
15664                        }
15665                    } else {
15666                        // Limit broadcast to their own package.
15667                        intent.setPackage(callerApp.info.packageName);
15668                    }
15669                }
15670            } catch (RemoteException e) {
15671                Slog.w(TAG, "Remote exception", e);
15672                return ActivityManager.BROADCAST_SUCCESS;
15673            }
15674        }
15675
15676        // Handle special intents: if this broadcast is from the package
15677        // manager about a package being removed, we need to remove all of
15678        // its activities from the history stack.
15679        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15680                intent.getAction());
15681        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15682                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15683                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15684                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15685                || uidRemoved) {
15686            if (checkComponentPermission(
15687                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15688                    callingPid, callingUid, -1, true)
15689                    == PackageManager.PERMISSION_GRANTED) {
15690                if (uidRemoved) {
15691                    final Bundle intentExtras = intent.getExtras();
15692                    final int uid = intentExtras != null
15693                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15694                    if (uid >= 0) {
15695                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15696                        synchronized (bs) {
15697                            bs.removeUidStatsLocked(uid);
15698                        }
15699                        mAppOpsService.uidRemoved(uid);
15700                    }
15701                } else {
15702                    // If resources are unavailable just force stop all
15703                    // those packages and flush the attribute cache as well.
15704                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15705                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15706                        if (list != null && (list.length > 0)) {
15707                            for (String pkg : list) {
15708                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15709                                        "storage unmount");
15710                            }
15711                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15712                            sendPackageBroadcastLocked(
15713                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15714                        }
15715                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15716                            intent.getAction())) {
15717                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15718                    } else {
15719                        Uri data = intent.getData();
15720                        String ssp;
15721                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15722                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15723                                    intent.getAction());
15724                            boolean fullUninstall = removed &&
15725                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15726                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15727                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15728                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15729                                        false, fullUninstall, userId,
15730                                        removed ? "pkg removed" : "pkg changed");
15731                            }
15732                            if (removed) {
15733                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15734                                        new String[] {ssp}, userId);
15735                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15736                                    mAppOpsService.packageRemoved(
15737                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15738
15739                                    // Remove all permissions granted from/to this package
15740                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15741                                }
15742                            }
15743                        }
15744                    }
15745                }
15746            } else {
15747                String msg = "Permission Denial: " + intent.getAction()
15748                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15749                        + ", uid=" + callingUid + ")"
15750                        + " requires "
15751                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15752                Slog.w(TAG, msg);
15753                throw new SecurityException(msg);
15754            }
15755
15756        // Special case for adding a package: by default turn on compatibility
15757        // mode.
15758        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15759            Uri data = intent.getData();
15760            String ssp;
15761            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15762                mCompatModePackages.handlePackageAddedLocked(ssp,
15763                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15764            }
15765        }
15766
15767        /*
15768         * If this is the time zone changed action, queue up a message that will reset the timezone
15769         * of all currently running processes. This message will get queued up before the broadcast
15770         * happens.
15771         */
15772        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15773            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15774        }
15775
15776        /*
15777         * If the user set the time, let all running processes know.
15778         */
15779        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15780            final int is24Hour = intent.getBooleanExtra(
15781                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15782            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15783            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15784            synchronized (stats) {
15785                stats.noteCurrentTimeChangedLocked();
15786            }
15787        }
15788
15789        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15790            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15791        }
15792
15793        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15794            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15795            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15796        }
15797
15798        // Add to the sticky list if requested.
15799        if (sticky) {
15800            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15801                    callingPid, callingUid)
15802                    != PackageManager.PERMISSION_GRANTED) {
15803                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15804                        + callingPid + ", uid=" + callingUid
15805                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15806                Slog.w(TAG, msg);
15807                throw new SecurityException(msg);
15808            }
15809            if (requiredPermission != null) {
15810                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15811                        + " and enforce permission " + requiredPermission);
15812                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15813            }
15814            if (intent.getComponent() != null) {
15815                throw new SecurityException(
15816                        "Sticky broadcasts can't target a specific component");
15817            }
15818            // We use userId directly here, since the "all" target is maintained
15819            // as a separate set of sticky broadcasts.
15820            if (userId != UserHandle.USER_ALL) {
15821                // But first, if this is not a broadcast to all users, then
15822                // make sure it doesn't conflict with an existing broadcast to
15823                // all users.
15824                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15825                        UserHandle.USER_ALL);
15826                if (stickies != null) {
15827                    ArrayList<Intent> list = stickies.get(intent.getAction());
15828                    if (list != null) {
15829                        int N = list.size();
15830                        int i;
15831                        for (i=0; i<N; i++) {
15832                            if (intent.filterEquals(list.get(i))) {
15833                                throw new IllegalArgumentException(
15834                                        "Sticky broadcast " + intent + " for user "
15835                                        + userId + " conflicts with existing global broadcast");
15836                            }
15837                        }
15838                    }
15839                }
15840            }
15841            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15842            if (stickies == null) {
15843                stickies = new ArrayMap<String, ArrayList<Intent>>();
15844                mStickyBroadcasts.put(userId, stickies);
15845            }
15846            ArrayList<Intent> list = stickies.get(intent.getAction());
15847            if (list == null) {
15848                list = new ArrayList<Intent>();
15849                stickies.put(intent.getAction(), list);
15850            }
15851            int N = list.size();
15852            int i;
15853            for (i=0; i<N; i++) {
15854                if (intent.filterEquals(list.get(i))) {
15855                    // This sticky already exists, replace it.
15856                    list.set(i, new Intent(intent));
15857                    break;
15858                }
15859            }
15860            if (i >= N) {
15861                list.add(new Intent(intent));
15862            }
15863        }
15864
15865        int[] users;
15866        if (userId == UserHandle.USER_ALL) {
15867            // Caller wants broadcast to go to all started users.
15868            users = mStartedUserArray;
15869        } else {
15870            // Caller wants broadcast to go to one specific user.
15871            users = new int[] {userId};
15872        }
15873
15874        // Figure out who all will receive this broadcast.
15875        List receivers = null;
15876        List<BroadcastFilter> registeredReceivers = null;
15877        // Need to resolve the intent to interested receivers...
15878        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15879                 == 0) {
15880            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15881        }
15882        if (intent.getComponent() == null) {
15883            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15884                // Query one target user at a time, excluding shell-restricted users
15885                UserManagerService ums = getUserManagerLocked();
15886                for (int i = 0; i < users.length; i++) {
15887                    if (ums.hasUserRestriction(
15888                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15889                        continue;
15890                    }
15891                    List<BroadcastFilter> registeredReceiversForUser =
15892                            mReceiverResolver.queryIntent(intent,
15893                                    resolvedType, false, users[i]);
15894                    if (registeredReceivers == null) {
15895                        registeredReceivers = registeredReceiversForUser;
15896                    } else if (registeredReceiversForUser != null) {
15897                        registeredReceivers.addAll(registeredReceiversForUser);
15898                    }
15899                }
15900            } else {
15901                registeredReceivers = mReceiverResolver.queryIntent(intent,
15902                        resolvedType, false, userId);
15903            }
15904        }
15905
15906        final boolean replacePending =
15907                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15908
15909        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15910                + " replacePending=" + replacePending);
15911
15912        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15913        if (!ordered && NR > 0) {
15914            // If we are not serializing this broadcast, then send the
15915            // registered receivers separately so they don't wait for the
15916            // components to be launched.
15917            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15918            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15919                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15920                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15921                    ordered, sticky, false, userId);
15922            if (DEBUG_BROADCAST) Slog.v(
15923                    TAG, "Enqueueing parallel broadcast " + r);
15924            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15925            if (!replaced) {
15926                queue.enqueueParallelBroadcastLocked(r);
15927                queue.scheduleBroadcastsLocked();
15928            }
15929            registeredReceivers = null;
15930            NR = 0;
15931        }
15932
15933        // Merge into one list.
15934        int ir = 0;
15935        if (receivers != null) {
15936            // A special case for PACKAGE_ADDED: do not allow the package
15937            // being added to see this broadcast.  This prevents them from
15938            // using this as a back door to get run as soon as they are
15939            // installed.  Maybe in the future we want to have a special install
15940            // broadcast or such for apps, but we'd like to deliberately make
15941            // this decision.
15942            String skipPackages[] = null;
15943            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15944                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15945                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15946                Uri data = intent.getData();
15947                if (data != null) {
15948                    String pkgName = data.getSchemeSpecificPart();
15949                    if (pkgName != null) {
15950                        skipPackages = new String[] { pkgName };
15951                    }
15952                }
15953            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15954                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15955            }
15956            if (skipPackages != null && (skipPackages.length > 0)) {
15957                for (String skipPackage : skipPackages) {
15958                    if (skipPackage != null) {
15959                        int NT = receivers.size();
15960                        for (int it=0; it<NT; it++) {
15961                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15962                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15963                                receivers.remove(it);
15964                                it--;
15965                                NT--;
15966                            }
15967                        }
15968                    }
15969                }
15970            }
15971
15972            int NT = receivers != null ? receivers.size() : 0;
15973            int it = 0;
15974            ResolveInfo curt = null;
15975            BroadcastFilter curr = null;
15976            while (it < NT && ir < NR) {
15977                if (curt == null) {
15978                    curt = (ResolveInfo)receivers.get(it);
15979                }
15980                if (curr == null) {
15981                    curr = registeredReceivers.get(ir);
15982                }
15983                if (curr.getPriority() >= curt.priority) {
15984                    // Insert this broadcast record into the final list.
15985                    receivers.add(it, curr);
15986                    ir++;
15987                    curr = null;
15988                    it++;
15989                    NT++;
15990                } else {
15991                    // Skip to the next ResolveInfo in the final list.
15992                    it++;
15993                    curt = null;
15994                }
15995            }
15996        }
15997        while (ir < NR) {
15998            if (receivers == null) {
15999                receivers = new ArrayList();
16000            }
16001            receivers.add(registeredReceivers.get(ir));
16002            ir++;
16003        }
16004
16005        if ((receivers != null && receivers.size() > 0)
16006                || resultTo != null) {
16007            BroadcastQueue queue = broadcastQueueForIntent(intent);
16008            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16009                    callerPackage, callingPid, callingUid, resolvedType,
16010                    requiredPermission, appOp, receivers, resultTo, resultCode,
16011                    resultData, map, ordered, sticky, false, userId);
16012            if (DEBUG_BROADCAST) Slog.v(
16013                    TAG, "Enqueueing ordered broadcast " + r
16014                    + ": prev had " + queue.mOrderedBroadcasts.size());
16015            if (DEBUG_BROADCAST) {
16016                int seq = r.intent.getIntExtra("seq", -1);
16017                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16018            }
16019            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16020            if (!replaced) {
16021                queue.enqueueOrderedBroadcastLocked(r);
16022                queue.scheduleBroadcastsLocked();
16023            }
16024        }
16025
16026        return ActivityManager.BROADCAST_SUCCESS;
16027    }
16028
16029    final Intent verifyBroadcastLocked(Intent intent) {
16030        // Refuse possible leaked file descriptors
16031        if (intent != null && intent.hasFileDescriptors() == true) {
16032            throw new IllegalArgumentException("File descriptors passed in Intent");
16033        }
16034
16035        int flags = intent.getFlags();
16036
16037        if (!mProcessesReady) {
16038            // if the caller really truly claims to know what they're doing, go
16039            // ahead and allow the broadcast without launching any receivers
16040            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16041                intent = new Intent(intent);
16042                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16043            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16044                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16045                        + " before boot completion");
16046                throw new IllegalStateException("Cannot broadcast before boot completed");
16047            }
16048        }
16049
16050        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16051            throw new IllegalArgumentException(
16052                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16053        }
16054
16055        return intent;
16056    }
16057
16058    public final int broadcastIntent(IApplicationThread caller,
16059            Intent intent, String resolvedType, IIntentReceiver resultTo,
16060            int resultCode, String resultData, Bundle map,
16061            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16062        enforceNotIsolatedCaller("broadcastIntent");
16063        synchronized(this) {
16064            intent = verifyBroadcastLocked(intent);
16065
16066            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16067            final int callingPid = Binder.getCallingPid();
16068            final int callingUid = Binder.getCallingUid();
16069            final long origId = Binder.clearCallingIdentity();
16070            int res = broadcastIntentLocked(callerApp,
16071                    callerApp != null ? callerApp.info.packageName : null,
16072                    intent, resolvedType, resultTo,
16073                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16074                    callingPid, callingUid, userId);
16075            Binder.restoreCallingIdentity(origId);
16076            return res;
16077        }
16078    }
16079
16080    int broadcastIntentInPackage(String packageName, int uid,
16081            Intent intent, String resolvedType, IIntentReceiver resultTo,
16082            int resultCode, String resultData, Bundle map,
16083            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16084        synchronized(this) {
16085            intent = verifyBroadcastLocked(intent);
16086
16087            final long origId = Binder.clearCallingIdentity();
16088            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16089                    resultTo, resultCode, resultData, map, requiredPermission,
16090                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16091            Binder.restoreCallingIdentity(origId);
16092            return res;
16093        }
16094    }
16095
16096    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16097        // Refuse possible leaked file descriptors
16098        if (intent != null && intent.hasFileDescriptors() == true) {
16099            throw new IllegalArgumentException("File descriptors passed in Intent");
16100        }
16101
16102        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16103                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16104
16105        synchronized(this) {
16106            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16107                    != PackageManager.PERMISSION_GRANTED) {
16108                String msg = "Permission Denial: unbroadcastIntent() from pid="
16109                        + Binder.getCallingPid()
16110                        + ", uid=" + Binder.getCallingUid()
16111                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16112                Slog.w(TAG, msg);
16113                throw new SecurityException(msg);
16114            }
16115            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16116            if (stickies != null) {
16117                ArrayList<Intent> list = stickies.get(intent.getAction());
16118                if (list != null) {
16119                    int N = list.size();
16120                    int i;
16121                    for (i=0; i<N; i++) {
16122                        if (intent.filterEquals(list.get(i))) {
16123                            list.remove(i);
16124                            break;
16125                        }
16126                    }
16127                    if (list.size() <= 0) {
16128                        stickies.remove(intent.getAction());
16129                    }
16130                }
16131                if (stickies.size() <= 0) {
16132                    mStickyBroadcasts.remove(userId);
16133                }
16134            }
16135        }
16136    }
16137
16138    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16139            String resultData, Bundle resultExtras, boolean resultAbort) {
16140        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16141        if (r == null) {
16142            Slog.w(TAG, "finishReceiver called but not found on queue");
16143            return false;
16144        }
16145
16146        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16147    }
16148
16149    void backgroundServicesFinishedLocked(int userId) {
16150        for (BroadcastQueue queue : mBroadcastQueues) {
16151            queue.backgroundServicesFinishedLocked(userId);
16152        }
16153    }
16154
16155    public void finishReceiver(IBinder who, int resultCode, String resultData,
16156            Bundle resultExtras, boolean resultAbort) {
16157        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16158
16159        // Refuse possible leaked file descriptors
16160        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16161            throw new IllegalArgumentException("File descriptors passed in Bundle");
16162        }
16163
16164        final long origId = Binder.clearCallingIdentity();
16165        try {
16166            boolean doNext = false;
16167            BroadcastRecord r;
16168
16169            synchronized(this) {
16170                r = broadcastRecordForReceiverLocked(who);
16171                if (r != null) {
16172                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16173                        resultData, resultExtras, resultAbort, true);
16174                }
16175            }
16176
16177            if (doNext) {
16178                r.queue.processNextBroadcast(false);
16179            }
16180            trimApplications();
16181        } finally {
16182            Binder.restoreCallingIdentity(origId);
16183        }
16184    }
16185
16186    // =========================================================
16187    // INSTRUMENTATION
16188    // =========================================================
16189
16190    public boolean startInstrumentation(ComponentName className,
16191            String profileFile, int flags, Bundle arguments,
16192            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16193            int userId, String abiOverride) {
16194        enforceNotIsolatedCaller("startInstrumentation");
16195        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16196                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16197        // Refuse possible leaked file descriptors
16198        if (arguments != null && arguments.hasFileDescriptors()) {
16199            throw new IllegalArgumentException("File descriptors passed in Bundle");
16200        }
16201
16202        synchronized(this) {
16203            InstrumentationInfo ii = null;
16204            ApplicationInfo ai = null;
16205            try {
16206                ii = mContext.getPackageManager().getInstrumentationInfo(
16207                    className, STOCK_PM_FLAGS);
16208                ai = AppGlobals.getPackageManager().getApplicationInfo(
16209                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16210            } catch (PackageManager.NameNotFoundException e) {
16211            } catch (RemoteException e) {
16212            }
16213            if (ii == null) {
16214                reportStartInstrumentationFailure(watcher, className,
16215                        "Unable to find instrumentation info for: " + className);
16216                return false;
16217            }
16218            if (ai == null) {
16219                reportStartInstrumentationFailure(watcher, className,
16220                        "Unable to find instrumentation target package: " + ii.targetPackage);
16221                return false;
16222            }
16223
16224            int match = mContext.getPackageManager().checkSignatures(
16225                    ii.targetPackage, ii.packageName);
16226            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16227                String msg = "Permission Denial: starting instrumentation "
16228                        + className + " from pid="
16229                        + Binder.getCallingPid()
16230                        + ", uid=" + Binder.getCallingPid()
16231                        + " not allowed because package " + ii.packageName
16232                        + " does not have a signature matching the target "
16233                        + ii.targetPackage;
16234                reportStartInstrumentationFailure(watcher, className, msg);
16235                throw new SecurityException(msg);
16236            }
16237
16238            final long origId = Binder.clearCallingIdentity();
16239            // Instrumentation can kill and relaunch even persistent processes
16240            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16241                    "start instr");
16242            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16243            app.instrumentationClass = className;
16244            app.instrumentationInfo = ai;
16245            app.instrumentationProfileFile = profileFile;
16246            app.instrumentationArguments = arguments;
16247            app.instrumentationWatcher = watcher;
16248            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16249            app.instrumentationResultClass = className;
16250            Binder.restoreCallingIdentity(origId);
16251        }
16252
16253        return true;
16254    }
16255
16256    /**
16257     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16258     * error to the logs, but if somebody is watching, send the report there too.  This enables
16259     * the "am" command to report errors with more information.
16260     *
16261     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16262     * @param cn The component name of the instrumentation.
16263     * @param report The error report.
16264     */
16265    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16266            ComponentName cn, String report) {
16267        Slog.w(TAG, report);
16268        try {
16269            if (watcher != null) {
16270                Bundle results = new Bundle();
16271                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16272                results.putString("Error", report);
16273                watcher.instrumentationStatus(cn, -1, results);
16274            }
16275        } catch (RemoteException e) {
16276            Slog.w(TAG, e);
16277        }
16278    }
16279
16280    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16281        if (app.instrumentationWatcher != null) {
16282            try {
16283                // NOTE:  IInstrumentationWatcher *must* be oneway here
16284                app.instrumentationWatcher.instrumentationFinished(
16285                    app.instrumentationClass,
16286                    resultCode,
16287                    results);
16288            } catch (RemoteException e) {
16289            }
16290        }
16291        if (app.instrumentationUiAutomationConnection != null) {
16292            try {
16293                app.instrumentationUiAutomationConnection.shutdown();
16294            } catch (RemoteException re) {
16295                /* ignore */
16296            }
16297            // Only a UiAutomation can set this flag and now that
16298            // it is finished we make sure it is reset to its default.
16299            mUserIsMonkey = false;
16300        }
16301        app.instrumentationWatcher = null;
16302        app.instrumentationUiAutomationConnection = null;
16303        app.instrumentationClass = null;
16304        app.instrumentationInfo = null;
16305        app.instrumentationProfileFile = null;
16306        app.instrumentationArguments = null;
16307
16308        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16309                "finished inst");
16310    }
16311
16312    public void finishInstrumentation(IApplicationThread target,
16313            int resultCode, Bundle results) {
16314        int userId = UserHandle.getCallingUserId();
16315        // Refuse possible leaked file descriptors
16316        if (results != null && results.hasFileDescriptors()) {
16317            throw new IllegalArgumentException("File descriptors passed in Intent");
16318        }
16319
16320        synchronized(this) {
16321            ProcessRecord app = getRecordForAppLocked(target);
16322            if (app == null) {
16323                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16324                return;
16325            }
16326            final long origId = Binder.clearCallingIdentity();
16327            finishInstrumentationLocked(app, resultCode, results);
16328            Binder.restoreCallingIdentity(origId);
16329        }
16330    }
16331
16332    // =========================================================
16333    // CONFIGURATION
16334    // =========================================================
16335
16336    public ConfigurationInfo getDeviceConfigurationInfo() {
16337        ConfigurationInfo config = new ConfigurationInfo();
16338        synchronized (this) {
16339            config.reqTouchScreen = mConfiguration.touchscreen;
16340            config.reqKeyboardType = mConfiguration.keyboard;
16341            config.reqNavigation = mConfiguration.navigation;
16342            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16343                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16344                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16345            }
16346            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16347                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16348                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16349            }
16350            config.reqGlEsVersion = GL_ES_VERSION;
16351        }
16352        return config;
16353    }
16354
16355    ActivityStack getFocusedStack() {
16356        return mStackSupervisor.getFocusedStack();
16357    }
16358
16359    public Configuration getConfiguration() {
16360        Configuration ci;
16361        synchronized(this) {
16362            ci = new Configuration(mConfiguration);
16363        }
16364        return ci;
16365    }
16366
16367    public void updatePersistentConfiguration(Configuration values) {
16368        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16369                "updateConfiguration()");
16370        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16371                "updateConfiguration()");
16372        if (values == null) {
16373            throw new NullPointerException("Configuration must not be null");
16374        }
16375
16376        synchronized(this) {
16377            final long origId = Binder.clearCallingIdentity();
16378            updateConfigurationLocked(values, null, true, false);
16379            Binder.restoreCallingIdentity(origId);
16380        }
16381    }
16382
16383    public void updateConfiguration(Configuration values) {
16384        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16385                "updateConfiguration()");
16386
16387        synchronized(this) {
16388            if (values == null && mWindowManager != null) {
16389                // sentinel: fetch the current configuration from the window manager
16390                values = mWindowManager.computeNewConfiguration();
16391            }
16392
16393            if (mWindowManager != null) {
16394                mProcessList.applyDisplaySize(mWindowManager);
16395            }
16396
16397            final long origId = Binder.clearCallingIdentity();
16398            if (values != null) {
16399                Settings.System.clearConfiguration(values);
16400            }
16401            updateConfigurationLocked(values, null, false, false);
16402            Binder.restoreCallingIdentity(origId);
16403        }
16404    }
16405
16406    /**
16407     * Do either or both things: (1) change the current configuration, and (2)
16408     * make sure the given activity is running with the (now) current
16409     * configuration.  Returns true if the activity has been left running, or
16410     * false if <var>starting</var> is being destroyed to match the new
16411     * configuration.
16412     * @param persistent TODO
16413     */
16414    boolean updateConfigurationLocked(Configuration values,
16415            ActivityRecord starting, boolean persistent, boolean initLocale) {
16416        int changes = 0;
16417
16418        if (values != null) {
16419            Configuration newConfig = new Configuration(mConfiguration);
16420            changes = newConfig.updateFrom(values);
16421            if (changes != 0) {
16422                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16423                    Slog.i(TAG, "Updating configuration to: " + values);
16424                }
16425
16426                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16427
16428                if (values.locale != null && !initLocale) {
16429                    saveLocaleLocked(values.locale,
16430                                     !values.locale.equals(mConfiguration.locale),
16431                                     values.userSetLocale);
16432                }
16433
16434                mConfigurationSeq++;
16435                if (mConfigurationSeq <= 0) {
16436                    mConfigurationSeq = 1;
16437                }
16438                newConfig.seq = mConfigurationSeq;
16439                mConfiguration = newConfig;
16440                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16441                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16442                //mUsageStatsService.noteStartConfig(newConfig);
16443
16444                final Configuration configCopy = new Configuration(mConfiguration);
16445
16446                // TODO: If our config changes, should we auto dismiss any currently
16447                // showing dialogs?
16448                mShowDialogs = shouldShowDialogs(newConfig);
16449
16450                AttributeCache ac = AttributeCache.instance();
16451                if (ac != null) {
16452                    ac.updateConfiguration(configCopy);
16453                }
16454
16455                // Make sure all resources in our process are updated
16456                // right now, so that anyone who is going to retrieve
16457                // resource values after we return will be sure to get
16458                // the new ones.  This is especially important during
16459                // boot, where the first config change needs to guarantee
16460                // all resources have that config before following boot
16461                // code is executed.
16462                mSystemThread.applyConfigurationToResources(configCopy);
16463
16464                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16465                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16466                    msg.obj = new Configuration(configCopy);
16467                    mHandler.sendMessage(msg);
16468                }
16469
16470                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16471                    ProcessRecord app = mLruProcesses.get(i);
16472                    try {
16473                        if (app.thread != null) {
16474                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16475                                    + app.processName + " new config " + mConfiguration);
16476                            app.thread.scheduleConfigurationChanged(configCopy);
16477                        }
16478                    } catch (Exception e) {
16479                    }
16480                }
16481                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16482                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16483                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16484                        | Intent.FLAG_RECEIVER_FOREGROUND);
16485                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16486                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16487                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16488                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16489                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16490                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16491                    broadcastIntentLocked(null, null, intent,
16492                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16493                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16494                }
16495            }
16496        }
16497
16498        boolean kept = true;
16499        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16500        // mainStack is null during startup.
16501        if (mainStack != null) {
16502            if (changes != 0 && starting == null) {
16503                // If the configuration changed, and the caller is not already
16504                // in the process of starting an activity, then find the top
16505                // activity to check if its configuration needs to change.
16506                starting = mainStack.topRunningActivityLocked(null);
16507            }
16508
16509            if (starting != null) {
16510                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16511                // And we need to make sure at this point that all other activities
16512                // are made visible with the correct configuration.
16513                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16514            }
16515        }
16516
16517        if (values != null && mWindowManager != null) {
16518            mWindowManager.setNewConfiguration(mConfiguration);
16519        }
16520
16521        return kept;
16522    }
16523
16524    /**
16525     * Decide based on the configuration whether we should shouw the ANR,
16526     * crash, etc dialogs.  The idea is that if there is no affordnace to
16527     * press the on-screen buttons, we shouldn't show the dialog.
16528     *
16529     * A thought: SystemUI might also want to get told about this, the Power
16530     * dialog / global actions also might want different behaviors.
16531     */
16532    private static final boolean shouldShowDialogs(Configuration config) {
16533        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16534                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16535    }
16536
16537    /**
16538     * Save the locale.  You must be inside a synchronized (this) block.
16539     */
16540    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16541        if(isDiff) {
16542            SystemProperties.set("user.language", l.getLanguage());
16543            SystemProperties.set("user.region", l.getCountry());
16544        }
16545
16546        if(isPersist) {
16547            SystemProperties.set("persist.sys.language", l.getLanguage());
16548            SystemProperties.set("persist.sys.country", l.getCountry());
16549            SystemProperties.set("persist.sys.localevar", l.getVariant());
16550
16551            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16552        }
16553    }
16554
16555    @Override
16556    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16557        synchronized (this) {
16558            ActivityRecord srec = ActivityRecord.forToken(token);
16559            if (srec.task != null && srec.task.stack != null) {
16560                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16561            }
16562        }
16563        return false;
16564    }
16565
16566    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16567            Intent resultData) {
16568
16569        synchronized (this) {
16570            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16571            if (stack != null) {
16572                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16573            }
16574            return false;
16575        }
16576    }
16577
16578    public int getLaunchedFromUid(IBinder activityToken) {
16579        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16580        if (srec == null) {
16581            return -1;
16582        }
16583        return srec.launchedFromUid;
16584    }
16585
16586    public String getLaunchedFromPackage(IBinder activityToken) {
16587        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16588        if (srec == null) {
16589            return null;
16590        }
16591        return srec.launchedFromPackage;
16592    }
16593
16594    // =========================================================
16595    // LIFETIME MANAGEMENT
16596    // =========================================================
16597
16598    // Returns which broadcast queue the app is the current [or imminent] receiver
16599    // on, or 'null' if the app is not an active broadcast recipient.
16600    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16601        BroadcastRecord r = app.curReceiver;
16602        if (r != null) {
16603            return r.queue;
16604        }
16605
16606        // It's not the current receiver, but it might be starting up to become one
16607        synchronized (this) {
16608            for (BroadcastQueue queue : mBroadcastQueues) {
16609                r = queue.mPendingBroadcast;
16610                if (r != null && r.curApp == app) {
16611                    // found it; report which queue it's in
16612                    return queue;
16613                }
16614            }
16615        }
16616
16617        return null;
16618    }
16619
16620    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16621            boolean doingAll, long now) {
16622        if (mAdjSeq == app.adjSeq) {
16623            // This adjustment has already been computed.
16624            return app.curRawAdj;
16625        }
16626
16627        if (app.thread == null) {
16628            app.adjSeq = mAdjSeq;
16629            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16630            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16631            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16632        }
16633
16634        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16635        app.adjSource = null;
16636        app.adjTarget = null;
16637        app.empty = false;
16638        app.cached = false;
16639
16640        final int activitiesSize = app.activities.size();
16641
16642        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16643            // The max adjustment doesn't allow this app to be anything
16644            // below foreground, so it is not worth doing work for it.
16645            app.adjType = "fixed";
16646            app.adjSeq = mAdjSeq;
16647            app.curRawAdj = app.maxAdj;
16648            app.foregroundActivities = false;
16649            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16650            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16651            // System processes can do UI, and when they do we want to have
16652            // them trim their memory after the user leaves the UI.  To
16653            // facilitate this, here we need to determine whether or not it
16654            // is currently showing UI.
16655            app.systemNoUi = true;
16656            if (app == TOP_APP) {
16657                app.systemNoUi = false;
16658            } else if (activitiesSize > 0) {
16659                for (int j = 0; j < activitiesSize; j++) {
16660                    final ActivityRecord r = app.activities.get(j);
16661                    if (r.visible) {
16662                        app.systemNoUi = false;
16663                    }
16664                }
16665            }
16666            if (!app.systemNoUi) {
16667                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16668            }
16669            return (app.curAdj=app.maxAdj);
16670        }
16671
16672        app.systemNoUi = false;
16673
16674        // Determine the importance of the process, starting with most
16675        // important to least, and assign an appropriate OOM adjustment.
16676        int adj;
16677        int schedGroup;
16678        int procState;
16679        boolean foregroundActivities = false;
16680        BroadcastQueue queue;
16681        if (app == TOP_APP) {
16682            // The last app on the list is the foreground app.
16683            adj = ProcessList.FOREGROUND_APP_ADJ;
16684            schedGroup = Process.THREAD_GROUP_DEFAULT;
16685            app.adjType = "top-activity";
16686            foregroundActivities = true;
16687            procState = ActivityManager.PROCESS_STATE_TOP;
16688        } else if (app.instrumentationClass != null) {
16689            // Don't want to kill running instrumentation.
16690            adj = ProcessList.FOREGROUND_APP_ADJ;
16691            schedGroup = Process.THREAD_GROUP_DEFAULT;
16692            app.adjType = "instrumentation";
16693            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16694        } else if ((queue = isReceivingBroadcast(app)) != null) {
16695            // An app that is currently receiving a broadcast also
16696            // counts as being in the foreground for OOM killer purposes.
16697            // It's placed in a sched group based on the nature of the
16698            // broadcast as reflected by which queue it's active in.
16699            adj = ProcessList.FOREGROUND_APP_ADJ;
16700            schedGroup = (queue == mFgBroadcastQueue)
16701                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16702            app.adjType = "broadcast";
16703            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16704        } else if (app.executingServices.size() > 0) {
16705            // An app that is currently executing a service callback also
16706            // counts as being in the foreground.
16707            adj = ProcessList.FOREGROUND_APP_ADJ;
16708            schedGroup = app.execServicesFg ?
16709                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16710            app.adjType = "exec-service";
16711            procState = ActivityManager.PROCESS_STATE_SERVICE;
16712            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16713        } else {
16714            // As far as we know the process is empty.  We may change our mind later.
16715            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16716            // At this point we don't actually know the adjustment.  Use the cached adj
16717            // value that the caller wants us to.
16718            adj = cachedAdj;
16719            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16720            app.cached = true;
16721            app.empty = true;
16722            app.adjType = "cch-empty";
16723        }
16724
16725        // Examine all activities if not already foreground.
16726        if (!foregroundActivities && activitiesSize > 0) {
16727            for (int j = 0; j < activitiesSize; j++) {
16728                final ActivityRecord r = app.activities.get(j);
16729                if (r.app != app) {
16730                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16731                            + app + "?!?");
16732                    continue;
16733                }
16734                if (r.visible) {
16735                    // App has a visible activity; only upgrade adjustment.
16736                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16737                        adj = ProcessList.VISIBLE_APP_ADJ;
16738                        app.adjType = "visible";
16739                    }
16740                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16741                        procState = ActivityManager.PROCESS_STATE_TOP;
16742                    }
16743                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16744                    app.cached = false;
16745                    app.empty = false;
16746                    foregroundActivities = true;
16747                    break;
16748                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16749                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16750                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16751                        app.adjType = "pausing";
16752                    }
16753                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16754                        procState = ActivityManager.PROCESS_STATE_TOP;
16755                    }
16756                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16757                    app.cached = false;
16758                    app.empty = false;
16759                    foregroundActivities = true;
16760                } else if (r.state == ActivityState.STOPPING) {
16761                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16762                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16763                        app.adjType = "stopping";
16764                    }
16765                    // For the process state, we will at this point consider the
16766                    // process to be cached.  It will be cached either as an activity
16767                    // or empty depending on whether the activity is finishing.  We do
16768                    // this so that we can treat the process as cached for purposes of
16769                    // memory trimming (determing current memory level, trim command to
16770                    // send to process) since there can be an arbitrary number of stopping
16771                    // processes and they should soon all go into the cached state.
16772                    if (!r.finishing) {
16773                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16774                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16775                        }
16776                    }
16777                    app.cached = false;
16778                    app.empty = false;
16779                    foregroundActivities = true;
16780                } else {
16781                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16782                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16783                        app.adjType = "cch-act";
16784                    }
16785                }
16786            }
16787        }
16788
16789        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16790            if (app.foregroundServices) {
16791                // The user is aware of this app, so make it visible.
16792                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16793                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16794                app.cached = false;
16795                app.adjType = "fg-service";
16796                schedGroup = Process.THREAD_GROUP_DEFAULT;
16797            } else if (app.forcingToForeground != null) {
16798                // The user is aware of this app, so make it visible.
16799                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16800                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16801                app.cached = false;
16802                app.adjType = "force-fg";
16803                app.adjSource = app.forcingToForeground;
16804                schedGroup = Process.THREAD_GROUP_DEFAULT;
16805            }
16806        }
16807
16808        if (app == mHeavyWeightProcess) {
16809            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16810                // We don't want to kill the current heavy-weight process.
16811                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16812                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16813                app.cached = false;
16814                app.adjType = "heavy";
16815            }
16816            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16817                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16818            }
16819        }
16820
16821        if (app == mHomeProcess) {
16822            if (adj > ProcessList.HOME_APP_ADJ) {
16823                // This process is hosting what we currently consider to be the
16824                // home app, so we don't want to let it go into the background.
16825                adj = ProcessList.HOME_APP_ADJ;
16826                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16827                app.cached = false;
16828                app.adjType = "home";
16829            }
16830            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16831                procState = ActivityManager.PROCESS_STATE_HOME;
16832            }
16833        }
16834
16835        if (app == mPreviousProcess && app.activities.size() > 0) {
16836            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16837                // This was the previous process that showed UI to the user.
16838                // We want to try to keep it around more aggressively, to give
16839                // a good experience around switching between two apps.
16840                adj = ProcessList.PREVIOUS_APP_ADJ;
16841                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16842                app.cached = false;
16843                app.adjType = "previous";
16844            }
16845            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16846                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16847            }
16848        }
16849
16850        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16851                + " reason=" + app.adjType);
16852
16853        // By default, we use the computed adjustment.  It may be changed if
16854        // there are applications dependent on our services or providers, but
16855        // this gives us a baseline and makes sure we don't get into an
16856        // infinite recursion.
16857        app.adjSeq = mAdjSeq;
16858        app.curRawAdj = adj;
16859        app.hasStartedServices = false;
16860
16861        if (mBackupTarget != null && app == mBackupTarget.app) {
16862            // If possible we want to avoid killing apps while they're being backed up
16863            if (adj > ProcessList.BACKUP_APP_ADJ) {
16864                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16865                adj = ProcessList.BACKUP_APP_ADJ;
16866                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16867                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16868                }
16869                app.adjType = "backup";
16870                app.cached = false;
16871            }
16872            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16873                procState = ActivityManager.PROCESS_STATE_BACKUP;
16874            }
16875        }
16876
16877        boolean mayBeTop = false;
16878
16879        for (int is = app.services.size()-1;
16880                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16881                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16882                        || procState > ActivityManager.PROCESS_STATE_TOP);
16883                is--) {
16884            ServiceRecord s = app.services.valueAt(is);
16885            if (s.startRequested) {
16886                app.hasStartedServices = true;
16887                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16888                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16889                }
16890                if (app.hasShownUi && app != mHomeProcess) {
16891                    // If this process has shown some UI, let it immediately
16892                    // go to the LRU list because it may be pretty heavy with
16893                    // UI stuff.  We'll tag it with a label just to help
16894                    // debug and understand what is going on.
16895                    if (adj > ProcessList.SERVICE_ADJ) {
16896                        app.adjType = "cch-started-ui-services";
16897                    }
16898                } else {
16899                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16900                        // This service has seen some activity within
16901                        // recent memory, so we will keep its process ahead
16902                        // of the background processes.
16903                        if (adj > ProcessList.SERVICE_ADJ) {
16904                            adj = ProcessList.SERVICE_ADJ;
16905                            app.adjType = "started-services";
16906                            app.cached = false;
16907                        }
16908                    }
16909                    // If we have let the service slide into the background
16910                    // state, still have some text describing what it is doing
16911                    // even though the service no longer has an impact.
16912                    if (adj > ProcessList.SERVICE_ADJ) {
16913                        app.adjType = "cch-started-services";
16914                    }
16915                }
16916            }
16917            for (int conni = s.connections.size()-1;
16918                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16919                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16920                            || procState > ActivityManager.PROCESS_STATE_TOP);
16921                    conni--) {
16922                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16923                for (int i = 0;
16924                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16925                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16926                                || procState > ActivityManager.PROCESS_STATE_TOP);
16927                        i++) {
16928                    // XXX should compute this based on the max of
16929                    // all connected clients.
16930                    ConnectionRecord cr = clist.get(i);
16931                    if (cr.binding.client == app) {
16932                        // Binding to ourself is not interesting.
16933                        continue;
16934                    }
16935                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16936                        ProcessRecord client = cr.binding.client;
16937                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16938                                TOP_APP, doingAll, now);
16939                        int clientProcState = client.curProcState;
16940                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16941                            // If the other app is cached for any reason, for purposes here
16942                            // we are going to consider it empty.  The specific cached state
16943                            // doesn't propagate except under certain conditions.
16944                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16945                        }
16946                        String adjType = null;
16947                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16948                            // Not doing bind OOM management, so treat
16949                            // this guy more like a started service.
16950                            if (app.hasShownUi && app != mHomeProcess) {
16951                                // If this process has shown some UI, let it immediately
16952                                // go to the LRU list because it may be pretty heavy with
16953                                // UI stuff.  We'll tag it with a label just to help
16954                                // debug and understand what is going on.
16955                                if (adj > clientAdj) {
16956                                    adjType = "cch-bound-ui-services";
16957                                }
16958                                app.cached = false;
16959                                clientAdj = adj;
16960                                clientProcState = procState;
16961                            } else {
16962                                if (now >= (s.lastActivity
16963                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16964                                    // This service has not seen activity within
16965                                    // recent memory, so allow it to drop to the
16966                                    // LRU list if there is no other reason to keep
16967                                    // it around.  We'll also tag it with a label just
16968                                    // to help debug and undertand what is going on.
16969                                    if (adj > clientAdj) {
16970                                        adjType = "cch-bound-services";
16971                                    }
16972                                    clientAdj = adj;
16973                                }
16974                            }
16975                        }
16976                        if (adj > clientAdj) {
16977                            // If this process has recently shown UI, and
16978                            // the process that is binding to it is less
16979                            // important than being visible, then we don't
16980                            // care about the binding as much as we care
16981                            // about letting this process get into the LRU
16982                            // list to be killed and restarted if needed for
16983                            // memory.
16984                            if (app.hasShownUi && app != mHomeProcess
16985                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16986                                adjType = "cch-bound-ui-services";
16987                            } else {
16988                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16989                                        |Context.BIND_IMPORTANT)) != 0) {
16990                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16991                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16992                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16993                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16994                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16995                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16996                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16997                                    adj = clientAdj;
16998                                } else {
16999                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17000                                        adj = ProcessList.VISIBLE_APP_ADJ;
17001                                    }
17002                                }
17003                                if (!client.cached) {
17004                                    app.cached = false;
17005                                }
17006                                adjType = "service";
17007                            }
17008                        }
17009                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17010                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17011                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17012                            }
17013                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17014                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17015                                    // Special handling of clients who are in the top state.
17016                                    // We *may* want to consider this process to be in the
17017                                    // top state as well, but only if there is not another
17018                                    // reason for it to be running.  Being on the top is a
17019                                    // special state, meaning you are specifically running
17020                                    // for the current top app.  If the process is already
17021                                    // running in the background for some other reason, it
17022                                    // is more important to continue considering it to be
17023                                    // in the background state.
17024                                    mayBeTop = true;
17025                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17026                                } else {
17027                                    // Special handling for above-top states (persistent
17028                                    // processes).  These should not bring the current process
17029                                    // into the top state, since they are not on top.  Instead
17030                                    // give them the best state after that.
17031                                    clientProcState =
17032                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17033                                }
17034                            }
17035                        } else {
17036                            if (clientProcState <
17037                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17038                                clientProcState =
17039                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17040                            }
17041                        }
17042                        if (procState > clientProcState) {
17043                            procState = clientProcState;
17044                        }
17045                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17046                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17047                            app.pendingUiClean = true;
17048                        }
17049                        if (adjType != null) {
17050                            app.adjType = adjType;
17051                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17052                                    .REASON_SERVICE_IN_USE;
17053                            app.adjSource = cr.binding.client;
17054                            app.adjSourceProcState = clientProcState;
17055                            app.adjTarget = s.name;
17056                        }
17057                    }
17058                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17059                        app.treatLikeActivity = true;
17060                    }
17061                    final ActivityRecord a = cr.activity;
17062                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17063                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17064                                (a.visible || a.state == ActivityState.RESUMED
17065                                 || a.state == ActivityState.PAUSING)) {
17066                            adj = ProcessList.FOREGROUND_APP_ADJ;
17067                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17068                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17069                            }
17070                            app.cached = false;
17071                            app.adjType = "service";
17072                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17073                                    .REASON_SERVICE_IN_USE;
17074                            app.adjSource = a;
17075                            app.adjSourceProcState = procState;
17076                            app.adjTarget = s.name;
17077                        }
17078                    }
17079                }
17080            }
17081        }
17082
17083        for (int provi = app.pubProviders.size()-1;
17084                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17085                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17086                        || procState > ActivityManager.PROCESS_STATE_TOP);
17087                provi--) {
17088            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17089            for (int i = cpr.connections.size()-1;
17090                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17091                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17092                            || procState > ActivityManager.PROCESS_STATE_TOP);
17093                    i--) {
17094                ContentProviderConnection conn = cpr.connections.get(i);
17095                ProcessRecord client = conn.client;
17096                if (client == app) {
17097                    // Being our own client is not interesting.
17098                    continue;
17099                }
17100                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17101                int clientProcState = client.curProcState;
17102                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17103                    // If the other app is cached for any reason, for purposes here
17104                    // we are going to consider it empty.
17105                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17106                }
17107                if (adj > clientAdj) {
17108                    if (app.hasShownUi && app != mHomeProcess
17109                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17110                        app.adjType = "cch-ui-provider";
17111                    } else {
17112                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17113                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17114                        app.adjType = "provider";
17115                    }
17116                    app.cached &= client.cached;
17117                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17118                            .REASON_PROVIDER_IN_USE;
17119                    app.adjSource = client;
17120                    app.adjSourceProcState = clientProcState;
17121                    app.adjTarget = cpr.name;
17122                }
17123                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17124                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17125                        // Special handling of clients who are in the top state.
17126                        // We *may* want to consider this process to be in the
17127                        // top state as well, but only if there is not another
17128                        // reason for it to be running.  Being on the top is a
17129                        // special state, meaning you are specifically running
17130                        // for the current top app.  If the process is already
17131                        // running in the background for some other reason, it
17132                        // is more important to continue considering it to be
17133                        // in the background state.
17134                        mayBeTop = true;
17135                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17136                    } else {
17137                        // Special handling for above-top states (persistent
17138                        // processes).  These should not bring the current process
17139                        // into the top state, since they are not on top.  Instead
17140                        // give them the best state after that.
17141                        clientProcState =
17142                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17143                    }
17144                }
17145                if (procState > clientProcState) {
17146                    procState = clientProcState;
17147                }
17148                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17149                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17150                }
17151            }
17152            // If the provider has external (non-framework) process
17153            // dependencies, ensure that its adjustment is at least
17154            // FOREGROUND_APP_ADJ.
17155            if (cpr.hasExternalProcessHandles()) {
17156                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17157                    adj = ProcessList.FOREGROUND_APP_ADJ;
17158                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17159                    app.cached = false;
17160                    app.adjType = "provider";
17161                    app.adjTarget = cpr.name;
17162                }
17163                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17164                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17165                }
17166            }
17167        }
17168
17169        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17170            // A client of one of our services or providers is in the top state.  We
17171            // *may* want to be in the top state, but not if we are already running in
17172            // the background for some other reason.  For the decision here, we are going
17173            // to pick out a few specific states that we want to remain in when a client
17174            // is top (states that tend to be longer-term) and otherwise allow it to go
17175            // to the top state.
17176            switch (procState) {
17177                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17178                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17179                case ActivityManager.PROCESS_STATE_SERVICE:
17180                    // These all are longer-term states, so pull them up to the top
17181                    // of the background states, but not all the way to the top state.
17182                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17183                    break;
17184                default:
17185                    // Otherwise, top is a better choice, so take it.
17186                    procState = ActivityManager.PROCESS_STATE_TOP;
17187                    break;
17188            }
17189        }
17190
17191        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17192            if (app.hasClientActivities) {
17193                // This is a cached process, but with client activities.  Mark it so.
17194                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17195                app.adjType = "cch-client-act";
17196            } else if (app.treatLikeActivity) {
17197                // This is a cached process, but somebody wants us to treat it like it has
17198                // an activity, okay!
17199                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17200                app.adjType = "cch-as-act";
17201            }
17202        }
17203
17204        if (adj == ProcessList.SERVICE_ADJ) {
17205            if (doingAll) {
17206                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17207                mNewNumServiceProcs++;
17208                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17209                if (!app.serviceb) {
17210                    // This service isn't far enough down on the LRU list to
17211                    // normally be a B service, but if we are low on RAM and it
17212                    // is large we want to force it down since we would prefer to
17213                    // keep launcher over it.
17214                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17215                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17216                        app.serviceHighRam = true;
17217                        app.serviceb = true;
17218                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17219                    } else {
17220                        mNewNumAServiceProcs++;
17221                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17222                    }
17223                } else {
17224                    app.serviceHighRam = false;
17225                }
17226            }
17227            if (app.serviceb) {
17228                adj = ProcessList.SERVICE_B_ADJ;
17229            }
17230        }
17231
17232        app.curRawAdj = adj;
17233
17234        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17235        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17236        if (adj > app.maxAdj) {
17237            adj = app.maxAdj;
17238            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17239                schedGroup = Process.THREAD_GROUP_DEFAULT;
17240            }
17241        }
17242
17243        // Do final modification to adj.  Everything we do between here and applying
17244        // the final setAdj must be done in this function, because we will also use
17245        // it when computing the final cached adj later.  Note that we don't need to
17246        // worry about this for max adj above, since max adj will always be used to
17247        // keep it out of the cached vaues.
17248        app.curAdj = app.modifyRawOomAdj(adj);
17249        app.curSchedGroup = schedGroup;
17250        app.curProcState = procState;
17251        app.foregroundActivities = foregroundActivities;
17252
17253        return app.curRawAdj;
17254    }
17255
17256    /**
17257     * Schedule PSS collection of a process.
17258     */
17259    void requestPssLocked(ProcessRecord proc, int procState) {
17260        if (mPendingPssProcesses.contains(proc)) {
17261            return;
17262        }
17263        if (mPendingPssProcesses.size() == 0) {
17264            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17265        }
17266        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17267        proc.pssProcState = procState;
17268        mPendingPssProcesses.add(proc);
17269    }
17270
17271    /**
17272     * Schedule PSS collection of all processes.
17273     */
17274    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17275        if (!always) {
17276            if (now < (mLastFullPssTime +
17277                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17278                return;
17279            }
17280        }
17281        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17282        mLastFullPssTime = now;
17283        mFullPssPending = true;
17284        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17285        mPendingPssProcesses.clear();
17286        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17287            ProcessRecord app = mLruProcesses.get(i);
17288            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17289                app.pssProcState = app.setProcState;
17290                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17291                        isSleeping(), now);
17292                mPendingPssProcesses.add(app);
17293            }
17294        }
17295        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17296    }
17297
17298    /**
17299     * Ask a given process to GC right now.
17300     */
17301    final void performAppGcLocked(ProcessRecord app) {
17302        try {
17303            app.lastRequestedGc = SystemClock.uptimeMillis();
17304            if (app.thread != null) {
17305                if (app.reportLowMemory) {
17306                    app.reportLowMemory = false;
17307                    app.thread.scheduleLowMemory();
17308                } else {
17309                    app.thread.processInBackground();
17310                }
17311            }
17312        } catch (Exception e) {
17313            // whatever.
17314        }
17315    }
17316
17317    /**
17318     * Returns true if things are idle enough to perform GCs.
17319     */
17320    private final boolean canGcNowLocked() {
17321        boolean processingBroadcasts = false;
17322        for (BroadcastQueue q : mBroadcastQueues) {
17323            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17324                processingBroadcasts = true;
17325            }
17326        }
17327        return !processingBroadcasts
17328                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17329    }
17330
17331    /**
17332     * Perform GCs on all processes that are waiting for it, but only
17333     * if things are idle.
17334     */
17335    final void performAppGcsLocked() {
17336        final int N = mProcessesToGc.size();
17337        if (N <= 0) {
17338            return;
17339        }
17340        if (canGcNowLocked()) {
17341            while (mProcessesToGc.size() > 0) {
17342                ProcessRecord proc = mProcessesToGc.remove(0);
17343                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17344                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17345                            <= SystemClock.uptimeMillis()) {
17346                        // To avoid spamming the system, we will GC processes one
17347                        // at a time, waiting a few seconds between each.
17348                        performAppGcLocked(proc);
17349                        scheduleAppGcsLocked();
17350                        return;
17351                    } else {
17352                        // It hasn't been long enough since we last GCed this
17353                        // process...  put it in the list to wait for its time.
17354                        addProcessToGcListLocked(proc);
17355                        break;
17356                    }
17357                }
17358            }
17359
17360            scheduleAppGcsLocked();
17361        }
17362    }
17363
17364    /**
17365     * If all looks good, perform GCs on all processes waiting for them.
17366     */
17367    final void performAppGcsIfAppropriateLocked() {
17368        if (canGcNowLocked()) {
17369            performAppGcsLocked();
17370            return;
17371        }
17372        // Still not idle, wait some more.
17373        scheduleAppGcsLocked();
17374    }
17375
17376    /**
17377     * Schedule the execution of all pending app GCs.
17378     */
17379    final void scheduleAppGcsLocked() {
17380        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17381
17382        if (mProcessesToGc.size() > 0) {
17383            // Schedule a GC for the time to the next process.
17384            ProcessRecord proc = mProcessesToGc.get(0);
17385            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17386
17387            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17388            long now = SystemClock.uptimeMillis();
17389            if (when < (now+GC_TIMEOUT)) {
17390                when = now + GC_TIMEOUT;
17391            }
17392            mHandler.sendMessageAtTime(msg, when);
17393        }
17394    }
17395
17396    /**
17397     * Add a process to the array of processes waiting to be GCed.  Keeps the
17398     * list in sorted order by the last GC time.  The process can't already be
17399     * on the list.
17400     */
17401    final void addProcessToGcListLocked(ProcessRecord proc) {
17402        boolean added = false;
17403        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17404            if (mProcessesToGc.get(i).lastRequestedGc <
17405                    proc.lastRequestedGc) {
17406                added = true;
17407                mProcessesToGc.add(i+1, proc);
17408                break;
17409            }
17410        }
17411        if (!added) {
17412            mProcessesToGc.add(0, proc);
17413        }
17414    }
17415
17416    /**
17417     * Set up to ask a process to GC itself.  This will either do it
17418     * immediately, or put it on the list of processes to gc the next
17419     * time things are idle.
17420     */
17421    final void scheduleAppGcLocked(ProcessRecord app) {
17422        long now = SystemClock.uptimeMillis();
17423        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17424            return;
17425        }
17426        if (!mProcessesToGc.contains(app)) {
17427            addProcessToGcListLocked(app);
17428            scheduleAppGcsLocked();
17429        }
17430    }
17431
17432    final void checkExcessivePowerUsageLocked(boolean doKills) {
17433        updateCpuStatsNow();
17434
17435        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17436        boolean doWakeKills = doKills;
17437        boolean doCpuKills = doKills;
17438        if (mLastPowerCheckRealtime == 0) {
17439            doWakeKills = false;
17440        }
17441        if (mLastPowerCheckUptime == 0) {
17442            doCpuKills = false;
17443        }
17444        if (stats.isScreenOn()) {
17445            doWakeKills = false;
17446        }
17447        final long curRealtime = SystemClock.elapsedRealtime();
17448        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17449        final long curUptime = SystemClock.uptimeMillis();
17450        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17451        mLastPowerCheckRealtime = curRealtime;
17452        mLastPowerCheckUptime = curUptime;
17453        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17454            doWakeKills = false;
17455        }
17456        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17457            doCpuKills = false;
17458        }
17459        int i = mLruProcesses.size();
17460        while (i > 0) {
17461            i--;
17462            ProcessRecord app = mLruProcesses.get(i);
17463            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17464                long wtime;
17465                synchronized (stats) {
17466                    wtime = stats.getProcessWakeTime(app.info.uid,
17467                            app.pid, curRealtime);
17468                }
17469                long wtimeUsed = wtime - app.lastWakeTime;
17470                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17471                if (DEBUG_POWER) {
17472                    StringBuilder sb = new StringBuilder(128);
17473                    sb.append("Wake for ");
17474                    app.toShortString(sb);
17475                    sb.append(": over ");
17476                    TimeUtils.formatDuration(realtimeSince, sb);
17477                    sb.append(" used ");
17478                    TimeUtils.formatDuration(wtimeUsed, sb);
17479                    sb.append(" (");
17480                    sb.append((wtimeUsed*100)/realtimeSince);
17481                    sb.append("%)");
17482                    Slog.i(TAG, sb.toString());
17483                    sb.setLength(0);
17484                    sb.append("CPU for ");
17485                    app.toShortString(sb);
17486                    sb.append(": over ");
17487                    TimeUtils.formatDuration(uptimeSince, sb);
17488                    sb.append(" used ");
17489                    TimeUtils.formatDuration(cputimeUsed, sb);
17490                    sb.append(" (");
17491                    sb.append((cputimeUsed*100)/uptimeSince);
17492                    sb.append("%)");
17493                    Slog.i(TAG, sb.toString());
17494                }
17495                // If a process has held a wake lock for more
17496                // than 50% of the time during this period,
17497                // that sounds bad.  Kill!
17498                if (doWakeKills && realtimeSince > 0
17499                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17500                    synchronized (stats) {
17501                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17502                                realtimeSince, wtimeUsed);
17503                    }
17504                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17505                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17506                } else if (doCpuKills && uptimeSince > 0
17507                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17508                    synchronized (stats) {
17509                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17510                                uptimeSince, cputimeUsed);
17511                    }
17512                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17513                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17514                } else {
17515                    app.lastWakeTime = wtime;
17516                    app.lastCpuTime = app.curCpuTime;
17517                }
17518            }
17519        }
17520    }
17521
17522    private final boolean applyOomAdjLocked(ProcessRecord app,
17523            ProcessRecord TOP_APP, boolean doingAll, long now) {
17524        boolean success = true;
17525
17526        if (app.curRawAdj != app.setRawAdj) {
17527            app.setRawAdj = app.curRawAdj;
17528        }
17529
17530        int changes = 0;
17531
17532        if (app.curAdj != app.setAdj) {
17533            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17534            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17535                TAG, "Set " + app.pid + " " + app.processName +
17536                " adj " + app.curAdj + ": " + app.adjType);
17537            app.setAdj = app.curAdj;
17538        }
17539
17540        if (app.setSchedGroup != app.curSchedGroup) {
17541            app.setSchedGroup = app.curSchedGroup;
17542            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17543                    "Setting process group of " + app.processName
17544                    + " to " + app.curSchedGroup);
17545            if (app.waitingToKill != null &&
17546                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17547                app.kill(app.waitingToKill, true);
17548                success = false;
17549            } else {
17550                if (true) {
17551                    long oldId = Binder.clearCallingIdentity();
17552                    try {
17553                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17554                    } catch (Exception e) {
17555                        Slog.w(TAG, "Failed setting process group of " + app.pid
17556                                + " to " + app.curSchedGroup);
17557                        e.printStackTrace();
17558                    } finally {
17559                        Binder.restoreCallingIdentity(oldId);
17560                    }
17561                } else {
17562                    if (app.thread != null) {
17563                        try {
17564                            app.thread.setSchedulingGroup(app.curSchedGroup);
17565                        } catch (RemoteException e) {
17566                        }
17567                    }
17568                }
17569                Process.setSwappiness(app.pid,
17570                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17571            }
17572        }
17573        if (app.repForegroundActivities != app.foregroundActivities) {
17574            app.repForegroundActivities = app.foregroundActivities;
17575            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17576        }
17577        if (app.repProcState != app.curProcState) {
17578            app.repProcState = app.curProcState;
17579            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17580            if (app.thread != null) {
17581                try {
17582                    if (false) {
17583                        //RuntimeException h = new RuntimeException("here");
17584                        Slog.i(TAG, "Sending new process state " + app.repProcState
17585                                + " to " + app /*, h*/);
17586                    }
17587                    app.thread.setProcessState(app.repProcState);
17588                } catch (RemoteException e) {
17589                }
17590            }
17591        }
17592        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17593                app.setProcState)) {
17594            app.lastStateTime = now;
17595            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17596                    isSleeping(), now);
17597            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17598                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17599                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17600                    + (app.nextPssTime-now) + ": " + app);
17601        } else {
17602            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17603                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17604                requestPssLocked(app, app.setProcState);
17605                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17606                        isSleeping(), now);
17607            } else if (false && DEBUG_PSS) {
17608                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17609            }
17610        }
17611        if (app.setProcState != app.curProcState) {
17612            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17613                    "Proc state change of " + app.processName
17614                    + " to " + app.curProcState);
17615            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17616            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17617            if (setImportant && !curImportant) {
17618                // This app is no longer something we consider important enough to allow to
17619                // use arbitrary amounts of battery power.  Note
17620                // its current wake lock time to later know to kill it if
17621                // it is not behaving well.
17622                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17623                synchronized (stats) {
17624                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17625                            app.pid, SystemClock.elapsedRealtime());
17626                }
17627                app.lastCpuTime = app.curCpuTime;
17628
17629            }
17630            app.setProcState = app.curProcState;
17631            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17632                app.notCachedSinceIdle = false;
17633            }
17634            if (!doingAll) {
17635                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17636            } else {
17637                app.procStateChanged = true;
17638            }
17639        }
17640
17641        if (changes != 0) {
17642            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17643            int i = mPendingProcessChanges.size()-1;
17644            ProcessChangeItem item = null;
17645            while (i >= 0) {
17646                item = mPendingProcessChanges.get(i);
17647                if (item.pid == app.pid) {
17648                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17649                    break;
17650                }
17651                i--;
17652            }
17653            if (i < 0) {
17654                // No existing item in pending changes; need a new one.
17655                final int NA = mAvailProcessChanges.size();
17656                if (NA > 0) {
17657                    item = mAvailProcessChanges.remove(NA-1);
17658                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17659                } else {
17660                    item = new ProcessChangeItem();
17661                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17662                }
17663                item.changes = 0;
17664                item.pid = app.pid;
17665                item.uid = app.info.uid;
17666                if (mPendingProcessChanges.size() == 0) {
17667                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17668                            "*** Enqueueing dispatch processes changed!");
17669                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17670                }
17671                mPendingProcessChanges.add(item);
17672            }
17673            item.changes |= changes;
17674            item.processState = app.repProcState;
17675            item.foregroundActivities = app.repForegroundActivities;
17676            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17677                    + Integer.toHexString(System.identityHashCode(item))
17678                    + " " + app.toShortString() + ": changes=" + item.changes
17679                    + " procState=" + item.processState
17680                    + " foreground=" + item.foregroundActivities
17681                    + " type=" + app.adjType + " source=" + app.adjSource
17682                    + " target=" + app.adjTarget);
17683        }
17684
17685        return success;
17686    }
17687
17688    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17689        if (proc.thread != null) {
17690            if (proc.baseProcessTracker != null) {
17691                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17692            }
17693            if (proc.repProcState >= 0) {
17694                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17695                        proc.repProcState);
17696            }
17697        }
17698    }
17699
17700    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17701            ProcessRecord TOP_APP, boolean doingAll, long now) {
17702        if (app.thread == null) {
17703            return false;
17704        }
17705
17706        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17707
17708        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17709    }
17710
17711    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17712            boolean oomAdj) {
17713        if (isForeground != proc.foregroundServices) {
17714            proc.foregroundServices = isForeground;
17715            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17716                    proc.info.uid);
17717            if (isForeground) {
17718                if (curProcs == null) {
17719                    curProcs = new ArrayList<ProcessRecord>();
17720                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17721                }
17722                if (!curProcs.contains(proc)) {
17723                    curProcs.add(proc);
17724                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17725                            proc.info.packageName, proc.info.uid);
17726                }
17727            } else {
17728                if (curProcs != null) {
17729                    if (curProcs.remove(proc)) {
17730                        mBatteryStatsService.noteEvent(
17731                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17732                                proc.info.packageName, proc.info.uid);
17733                        if (curProcs.size() <= 0) {
17734                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17735                        }
17736                    }
17737                }
17738            }
17739            if (oomAdj) {
17740                updateOomAdjLocked();
17741            }
17742        }
17743    }
17744
17745    private final ActivityRecord resumedAppLocked() {
17746        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17747        String pkg;
17748        int uid;
17749        if (act != null) {
17750            pkg = act.packageName;
17751            uid = act.info.applicationInfo.uid;
17752        } else {
17753            pkg = null;
17754            uid = -1;
17755        }
17756        // Has the UID or resumed package name changed?
17757        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17758                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17759            if (mCurResumedPackage != null) {
17760                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17761                        mCurResumedPackage, mCurResumedUid);
17762            }
17763            mCurResumedPackage = pkg;
17764            mCurResumedUid = uid;
17765            if (mCurResumedPackage != null) {
17766                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17767                        mCurResumedPackage, mCurResumedUid);
17768            }
17769        }
17770        return act;
17771    }
17772
17773    final boolean updateOomAdjLocked(ProcessRecord app) {
17774        final ActivityRecord TOP_ACT = resumedAppLocked();
17775        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17776        final boolean wasCached = app.cached;
17777
17778        mAdjSeq++;
17779
17780        // This is the desired cached adjusment we want to tell it to use.
17781        // If our app is currently cached, we know it, and that is it.  Otherwise,
17782        // we don't know it yet, and it needs to now be cached we will then
17783        // need to do a complete oom adj.
17784        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17785                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17786        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17787                SystemClock.uptimeMillis());
17788        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17789            // Changed to/from cached state, so apps after it in the LRU
17790            // list may also be changed.
17791            updateOomAdjLocked();
17792        }
17793        return success;
17794    }
17795
17796    final void updateOomAdjLocked() {
17797        final ActivityRecord TOP_ACT = resumedAppLocked();
17798        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17799        final long now = SystemClock.uptimeMillis();
17800        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17801        final int N = mLruProcesses.size();
17802
17803        if (false) {
17804            RuntimeException e = new RuntimeException();
17805            e.fillInStackTrace();
17806            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17807        }
17808
17809        mAdjSeq++;
17810        mNewNumServiceProcs = 0;
17811        mNewNumAServiceProcs = 0;
17812
17813        final int emptyProcessLimit;
17814        final int cachedProcessLimit;
17815        if (mProcessLimit <= 0) {
17816            emptyProcessLimit = cachedProcessLimit = 0;
17817        } else if (mProcessLimit == 1) {
17818            emptyProcessLimit = 1;
17819            cachedProcessLimit = 0;
17820        } else {
17821            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17822            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17823        }
17824
17825        // Let's determine how many processes we have running vs.
17826        // how many slots we have for background processes; we may want
17827        // to put multiple processes in a slot of there are enough of
17828        // them.
17829        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17830                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17831        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17832        if (numEmptyProcs > cachedProcessLimit) {
17833            // If there are more empty processes than our limit on cached
17834            // processes, then use the cached process limit for the factor.
17835            // This ensures that the really old empty processes get pushed
17836            // down to the bottom, so if we are running low on memory we will
17837            // have a better chance at keeping around more cached processes
17838            // instead of a gazillion empty processes.
17839            numEmptyProcs = cachedProcessLimit;
17840        }
17841        int emptyFactor = numEmptyProcs/numSlots;
17842        if (emptyFactor < 1) emptyFactor = 1;
17843        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17844        if (cachedFactor < 1) cachedFactor = 1;
17845        int stepCached = 0;
17846        int stepEmpty = 0;
17847        int numCached = 0;
17848        int numEmpty = 0;
17849        int numTrimming = 0;
17850
17851        mNumNonCachedProcs = 0;
17852        mNumCachedHiddenProcs = 0;
17853
17854        // First update the OOM adjustment for each of the
17855        // application processes based on their current state.
17856        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17857        int nextCachedAdj = curCachedAdj+1;
17858        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17859        int nextEmptyAdj = curEmptyAdj+2;
17860        for (int i=N-1; i>=0; i--) {
17861            ProcessRecord app = mLruProcesses.get(i);
17862            if (!app.killedByAm && app.thread != null) {
17863                app.procStateChanged = false;
17864                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17865
17866                // If we haven't yet assigned the final cached adj
17867                // to the process, do that now.
17868                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17869                    switch (app.curProcState) {
17870                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17871                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17872                            // This process is a cached process holding activities...
17873                            // assign it the next cached value for that type, and then
17874                            // step that cached level.
17875                            app.curRawAdj = curCachedAdj;
17876                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17877                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17878                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17879                                    + ")");
17880                            if (curCachedAdj != nextCachedAdj) {
17881                                stepCached++;
17882                                if (stepCached >= cachedFactor) {
17883                                    stepCached = 0;
17884                                    curCachedAdj = nextCachedAdj;
17885                                    nextCachedAdj += 2;
17886                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17887                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17888                                    }
17889                                }
17890                            }
17891                            break;
17892                        default:
17893                            // For everything else, assign next empty cached process
17894                            // level and bump that up.  Note that this means that
17895                            // long-running services that have dropped down to the
17896                            // cached level will be treated as empty (since their process
17897                            // state is still as a service), which is what we want.
17898                            app.curRawAdj = curEmptyAdj;
17899                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17900                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17901                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17902                                    + ")");
17903                            if (curEmptyAdj != nextEmptyAdj) {
17904                                stepEmpty++;
17905                                if (stepEmpty >= emptyFactor) {
17906                                    stepEmpty = 0;
17907                                    curEmptyAdj = nextEmptyAdj;
17908                                    nextEmptyAdj += 2;
17909                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17910                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17911                                    }
17912                                }
17913                            }
17914                            break;
17915                    }
17916                }
17917
17918                applyOomAdjLocked(app, TOP_APP, true, now);
17919
17920                // Count the number of process types.
17921                switch (app.curProcState) {
17922                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17923                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17924                        mNumCachedHiddenProcs++;
17925                        numCached++;
17926                        if (numCached > cachedProcessLimit) {
17927                            app.kill("cached #" + numCached, true);
17928                        }
17929                        break;
17930                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17931                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17932                                && app.lastActivityTime < oldTime) {
17933                            app.kill("empty for "
17934                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17935                                    / 1000) + "s", true);
17936                        } else {
17937                            numEmpty++;
17938                            if (numEmpty > emptyProcessLimit) {
17939                                app.kill("empty #" + numEmpty, true);
17940                            }
17941                        }
17942                        break;
17943                    default:
17944                        mNumNonCachedProcs++;
17945                        break;
17946                }
17947
17948                if (app.isolated && app.services.size() <= 0) {
17949                    // If this is an isolated process, and there are no
17950                    // services running in it, then the process is no longer
17951                    // needed.  We agressively kill these because we can by
17952                    // definition not re-use the same process again, and it is
17953                    // good to avoid having whatever code was running in them
17954                    // left sitting around after no longer needed.
17955                    app.kill("isolated not needed", true);
17956                }
17957
17958                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17959                        && !app.killedByAm) {
17960                    numTrimming++;
17961                }
17962            }
17963        }
17964
17965        mNumServiceProcs = mNewNumServiceProcs;
17966
17967        // Now determine the memory trimming level of background processes.
17968        // Unfortunately we need to start at the back of the list to do this
17969        // properly.  We only do this if the number of background apps we
17970        // are managing to keep around is less than half the maximum we desire;
17971        // if we are keeping a good number around, we'll let them use whatever
17972        // memory they want.
17973        final int numCachedAndEmpty = numCached + numEmpty;
17974        int memFactor;
17975        if (numCached <= ProcessList.TRIM_CACHED_APPS
17976                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17977            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17978                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17979            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17980                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17981            } else {
17982                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17983            }
17984        } else {
17985            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17986        }
17987        // We always allow the memory level to go up (better).  We only allow it to go
17988        // down if we are in a state where that is allowed, *and* the total number of processes
17989        // has gone down since last time.
17990        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17991                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17992                + " last=" + mLastNumProcesses);
17993        if (memFactor > mLastMemoryLevel) {
17994            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17995                memFactor = mLastMemoryLevel;
17996                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17997            }
17998        }
17999        mLastMemoryLevel = memFactor;
18000        mLastNumProcesses = mLruProcesses.size();
18001        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18002        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18003        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18004            if (mLowRamStartTime == 0) {
18005                mLowRamStartTime = now;
18006            }
18007            int step = 0;
18008            int fgTrimLevel;
18009            switch (memFactor) {
18010                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18011                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18012                    break;
18013                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18014                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18015                    break;
18016                default:
18017                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18018                    break;
18019            }
18020            int factor = numTrimming/3;
18021            int minFactor = 2;
18022            if (mHomeProcess != null) minFactor++;
18023            if (mPreviousProcess != null) minFactor++;
18024            if (factor < minFactor) factor = minFactor;
18025            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18026            for (int i=N-1; i>=0; i--) {
18027                ProcessRecord app = mLruProcesses.get(i);
18028                if (allChanged || app.procStateChanged) {
18029                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18030                    app.procStateChanged = false;
18031                }
18032                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18033                        && !app.killedByAm) {
18034                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18035                        try {
18036                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18037                                    "Trimming memory of " + app.processName
18038                                    + " to " + curLevel);
18039                            app.thread.scheduleTrimMemory(curLevel);
18040                        } catch (RemoteException e) {
18041                        }
18042                        if (false) {
18043                            // For now we won't do this; our memory trimming seems
18044                            // to be good enough at this point that destroying
18045                            // activities causes more harm than good.
18046                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18047                                    && app != mHomeProcess && app != mPreviousProcess) {
18048                                // Need to do this on its own message because the stack may not
18049                                // be in a consistent state at this point.
18050                                // For these apps we will also finish their activities
18051                                // to help them free memory.
18052                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18053                            }
18054                        }
18055                    }
18056                    app.trimMemoryLevel = curLevel;
18057                    step++;
18058                    if (step >= factor) {
18059                        step = 0;
18060                        switch (curLevel) {
18061                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18062                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18063                                break;
18064                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18065                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18066                                break;
18067                        }
18068                    }
18069                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18070                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18071                            && app.thread != null) {
18072                        try {
18073                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18074                                    "Trimming memory of heavy-weight " + app.processName
18075                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18076                            app.thread.scheduleTrimMemory(
18077                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18078                        } catch (RemoteException e) {
18079                        }
18080                    }
18081                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18082                } else {
18083                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18084                            || app.systemNoUi) && app.pendingUiClean) {
18085                        // If this application is now in the background and it
18086                        // had done UI, then give it the special trim level to
18087                        // have it free UI resources.
18088                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18089                        if (app.trimMemoryLevel < level && app.thread != null) {
18090                            try {
18091                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18092                                        "Trimming memory of bg-ui " + app.processName
18093                                        + " to " + level);
18094                                app.thread.scheduleTrimMemory(level);
18095                            } catch (RemoteException e) {
18096                            }
18097                        }
18098                        app.pendingUiClean = false;
18099                    }
18100                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18101                        try {
18102                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18103                                    "Trimming memory of fg " + app.processName
18104                                    + " to " + fgTrimLevel);
18105                            app.thread.scheduleTrimMemory(fgTrimLevel);
18106                        } catch (RemoteException e) {
18107                        }
18108                    }
18109                    app.trimMemoryLevel = fgTrimLevel;
18110                }
18111            }
18112        } else {
18113            if (mLowRamStartTime != 0) {
18114                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18115                mLowRamStartTime = 0;
18116            }
18117            for (int i=N-1; i>=0; i--) {
18118                ProcessRecord app = mLruProcesses.get(i);
18119                if (allChanged || app.procStateChanged) {
18120                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18121                    app.procStateChanged = false;
18122                }
18123                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18124                        || app.systemNoUi) && app.pendingUiClean) {
18125                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18126                            && app.thread != null) {
18127                        try {
18128                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18129                                    "Trimming memory of ui hidden " + app.processName
18130                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18131                            app.thread.scheduleTrimMemory(
18132                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18133                        } catch (RemoteException e) {
18134                        }
18135                    }
18136                    app.pendingUiClean = false;
18137                }
18138                app.trimMemoryLevel = 0;
18139            }
18140        }
18141
18142        if (mAlwaysFinishActivities) {
18143            // Need to do this on its own message because the stack may not
18144            // be in a consistent state at this point.
18145            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18146        }
18147
18148        if (allChanged) {
18149            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18150        }
18151
18152        if (mProcessStats.shouldWriteNowLocked(now)) {
18153            mHandler.post(new Runnable() {
18154                @Override public void run() {
18155                    synchronized (ActivityManagerService.this) {
18156                        mProcessStats.writeStateAsyncLocked();
18157                    }
18158                }
18159            });
18160        }
18161
18162        if (DEBUG_OOM_ADJ) {
18163            if (false) {
18164                RuntimeException here = new RuntimeException("here");
18165                here.fillInStackTrace();
18166                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18167            } else {
18168                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18169            }
18170        }
18171    }
18172
18173    final void trimApplications() {
18174        synchronized (this) {
18175            int i;
18176
18177            // First remove any unused application processes whose package
18178            // has been removed.
18179            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18180                final ProcessRecord app = mRemovedProcesses.get(i);
18181                if (app.activities.size() == 0
18182                        && app.curReceiver == null && app.services.size() == 0) {
18183                    Slog.i(
18184                        TAG, "Exiting empty application process "
18185                        + app.processName + " ("
18186                        + (app.thread != null ? app.thread.asBinder() : null)
18187                        + ")\n");
18188                    if (app.pid > 0 && app.pid != MY_PID) {
18189                        app.kill("empty", false);
18190                    } else {
18191                        try {
18192                            app.thread.scheduleExit();
18193                        } catch (Exception e) {
18194                            // Ignore exceptions.
18195                        }
18196                    }
18197                    cleanUpApplicationRecordLocked(app, false, true, -1);
18198                    mRemovedProcesses.remove(i);
18199
18200                    if (app.persistent) {
18201                        addAppLocked(app.info, false, null /* ABI override */);
18202                    }
18203                }
18204            }
18205
18206            // Now update the oom adj for all processes.
18207            updateOomAdjLocked();
18208        }
18209    }
18210
18211    /** This method sends the specified signal to each of the persistent apps */
18212    public void signalPersistentProcesses(int sig) throws RemoteException {
18213        if (sig != Process.SIGNAL_USR1) {
18214            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18215        }
18216
18217        synchronized (this) {
18218            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18219                    != PackageManager.PERMISSION_GRANTED) {
18220                throw new SecurityException("Requires permission "
18221                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18222            }
18223
18224            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18225                ProcessRecord r = mLruProcesses.get(i);
18226                if (r.thread != null && r.persistent) {
18227                    Process.sendSignal(r.pid, sig);
18228                }
18229            }
18230        }
18231    }
18232
18233    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18234        if (proc == null || proc == mProfileProc) {
18235            proc = mProfileProc;
18236            profileType = mProfileType;
18237            clearProfilerLocked();
18238        }
18239        if (proc == null) {
18240            return;
18241        }
18242        try {
18243            proc.thread.profilerControl(false, null, profileType);
18244        } catch (RemoteException e) {
18245            throw new IllegalStateException("Process disappeared");
18246        }
18247    }
18248
18249    private void clearProfilerLocked() {
18250        if (mProfileFd != null) {
18251            try {
18252                mProfileFd.close();
18253            } catch (IOException e) {
18254            }
18255        }
18256        mProfileApp = null;
18257        mProfileProc = null;
18258        mProfileFile = null;
18259        mProfileType = 0;
18260        mAutoStopProfiler = false;
18261        mSamplingInterval = 0;
18262    }
18263
18264    public boolean profileControl(String process, int userId, boolean start,
18265            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18266
18267        try {
18268            synchronized (this) {
18269                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18270                // its own permission.
18271                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18272                        != PackageManager.PERMISSION_GRANTED) {
18273                    throw new SecurityException("Requires permission "
18274                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18275                }
18276
18277                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18278                    throw new IllegalArgumentException("null profile info or fd");
18279                }
18280
18281                ProcessRecord proc = null;
18282                if (process != null) {
18283                    proc = findProcessLocked(process, userId, "profileControl");
18284                }
18285
18286                if (start && (proc == null || proc.thread == null)) {
18287                    throw new IllegalArgumentException("Unknown process: " + process);
18288                }
18289
18290                if (start) {
18291                    stopProfilerLocked(null, 0);
18292                    setProfileApp(proc.info, proc.processName, profilerInfo);
18293                    mProfileProc = proc;
18294                    mProfileType = profileType;
18295                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18296                    try {
18297                        fd = fd.dup();
18298                    } catch (IOException e) {
18299                        fd = null;
18300                    }
18301                    profilerInfo.profileFd = fd;
18302                    proc.thread.profilerControl(start, profilerInfo, profileType);
18303                    fd = null;
18304                    mProfileFd = null;
18305                } else {
18306                    stopProfilerLocked(proc, profileType);
18307                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18308                        try {
18309                            profilerInfo.profileFd.close();
18310                        } catch (IOException e) {
18311                        }
18312                    }
18313                }
18314
18315                return true;
18316            }
18317        } catch (RemoteException e) {
18318            throw new IllegalStateException("Process disappeared");
18319        } finally {
18320            if (profilerInfo != null && profilerInfo.profileFd != null) {
18321                try {
18322                    profilerInfo.profileFd.close();
18323                } catch (IOException e) {
18324                }
18325            }
18326        }
18327    }
18328
18329    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18330        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18331                userId, true, ALLOW_FULL_ONLY, callName, null);
18332        ProcessRecord proc = null;
18333        try {
18334            int pid = Integer.parseInt(process);
18335            synchronized (mPidsSelfLocked) {
18336                proc = mPidsSelfLocked.get(pid);
18337            }
18338        } catch (NumberFormatException e) {
18339        }
18340
18341        if (proc == null) {
18342            ArrayMap<String, SparseArray<ProcessRecord>> all
18343                    = mProcessNames.getMap();
18344            SparseArray<ProcessRecord> procs = all.get(process);
18345            if (procs != null && procs.size() > 0) {
18346                proc = procs.valueAt(0);
18347                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18348                    for (int i=1; i<procs.size(); i++) {
18349                        ProcessRecord thisProc = procs.valueAt(i);
18350                        if (thisProc.userId == userId) {
18351                            proc = thisProc;
18352                            break;
18353                        }
18354                    }
18355                }
18356            }
18357        }
18358
18359        return proc;
18360    }
18361
18362    public boolean dumpHeap(String process, int userId, boolean managed,
18363            String path, ParcelFileDescriptor fd) throws RemoteException {
18364
18365        try {
18366            synchronized (this) {
18367                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18368                // its own permission (same as profileControl).
18369                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18370                        != PackageManager.PERMISSION_GRANTED) {
18371                    throw new SecurityException("Requires permission "
18372                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18373                }
18374
18375                if (fd == null) {
18376                    throw new IllegalArgumentException("null fd");
18377                }
18378
18379                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18380                if (proc == null || proc.thread == null) {
18381                    throw new IllegalArgumentException("Unknown process: " + process);
18382                }
18383
18384                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18385                if (!isDebuggable) {
18386                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18387                        throw new SecurityException("Process not debuggable: " + proc);
18388                    }
18389                }
18390
18391                proc.thread.dumpHeap(managed, path, fd);
18392                fd = null;
18393                return true;
18394            }
18395        } catch (RemoteException e) {
18396            throw new IllegalStateException("Process disappeared");
18397        } finally {
18398            if (fd != null) {
18399                try {
18400                    fd.close();
18401                } catch (IOException e) {
18402                }
18403            }
18404        }
18405    }
18406
18407    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18408    public void monitor() {
18409        synchronized (this) { }
18410    }
18411
18412    void onCoreSettingsChange(Bundle settings) {
18413        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18414            ProcessRecord processRecord = mLruProcesses.get(i);
18415            try {
18416                if (processRecord.thread != null) {
18417                    processRecord.thread.setCoreSettings(settings);
18418                }
18419            } catch (RemoteException re) {
18420                /* ignore */
18421            }
18422        }
18423    }
18424
18425    // Multi-user methods
18426
18427    /**
18428     * Start user, if its not already running, but don't bring it to foreground.
18429     */
18430    @Override
18431    public boolean startUserInBackground(final int userId) {
18432        return startUser(userId, /* foreground */ false);
18433    }
18434
18435    /**
18436     * Start user, if its not already running, and bring it to foreground.
18437     */
18438    boolean startUserInForeground(final int userId, Dialog dlg) {
18439        boolean result = startUser(userId, /* foreground */ true);
18440        dlg.dismiss();
18441        return result;
18442    }
18443
18444    /**
18445     * Refreshes the list of users related to the current user when either a
18446     * user switch happens or when a new related user is started in the
18447     * background.
18448     */
18449    private void updateCurrentProfileIdsLocked() {
18450        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18451                mCurrentUserId, false /* enabledOnly */);
18452        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18453        for (int i = 0; i < currentProfileIds.length; i++) {
18454            currentProfileIds[i] = profiles.get(i).id;
18455        }
18456        mCurrentProfileIds = currentProfileIds;
18457
18458        synchronized (mUserProfileGroupIdsSelfLocked) {
18459            mUserProfileGroupIdsSelfLocked.clear();
18460            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18461            for (int i = 0; i < users.size(); i++) {
18462                UserInfo user = users.get(i);
18463                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18464                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18465                }
18466            }
18467        }
18468    }
18469
18470    private Set getProfileIdsLocked(int userId) {
18471        Set userIds = new HashSet<Integer>();
18472        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18473                userId, false /* enabledOnly */);
18474        for (UserInfo user : profiles) {
18475            userIds.add(Integer.valueOf(user.id));
18476        }
18477        return userIds;
18478    }
18479
18480    @Override
18481    public boolean switchUser(final int userId) {
18482        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18483        String userName;
18484        synchronized (this) {
18485            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18486            if (userInfo == null) {
18487                Slog.w(TAG, "No user info for user #" + userId);
18488                return false;
18489            }
18490            if (userInfo.isManagedProfile()) {
18491                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18492                return false;
18493            }
18494            userName = userInfo.name;
18495            mTargetUserId = userId;
18496        }
18497        mHandler.removeMessages(START_USER_SWITCH_MSG);
18498        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18499        return true;
18500    }
18501
18502    private void showUserSwitchDialog(int userId, String userName) {
18503        // The dialog will show and then initiate the user switch by calling startUserInForeground
18504        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18505                true /* above system */);
18506        d.show();
18507    }
18508
18509    private boolean startUser(final int userId, final boolean foreground) {
18510        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18511                != PackageManager.PERMISSION_GRANTED) {
18512            String msg = "Permission Denial: switchUser() from pid="
18513                    + Binder.getCallingPid()
18514                    + ", uid=" + Binder.getCallingUid()
18515                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18516            Slog.w(TAG, msg);
18517            throw new SecurityException(msg);
18518        }
18519
18520        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18521
18522        final long ident = Binder.clearCallingIdentity();
18523        try {
18524            synchronized (this) {
18525                final int oldUserId = mCurrentUserId;
18526                if (oldUserId == userId) {
18527                    return true;
18528                }
18529
18530                mStackSupervisor.setLockTaskModeLocked(null, false);
18531
18532                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18533                if (userInfo == null) {
18534                    Slog.w(TAG, "No user info for user #" + userId);
18535                    return false;
18536                }
18537                if (foreground && userInfo.isManagedProfile()) {
18538                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18539                    return false;
18540                }
18541
18542                if (foreground) {
18543                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18544                            R.anim.screen_user_enter);
18545                }
18546
18547                boolean needStart = false;
18548
18549                // If the user we are switching to is not currently started, then
18550                // we need to start it now.
18551                if (mStartedUsers.get(userId) == null) {
18552                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18553                    updateStartedUserArrayLocked();
18554                    needStart = true;
18555                }
18556
18557                final Integer userIdInt = Integer.valueOf(userId);
18558                mUserLru.remove(userIdInt);
18559                mUserLru.add(userIdInt);
18560
18561                if (foreground) {
18562                    mCurrentUserId = userId;
18563                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18564                    updateCurrentProfileIdsLocked();
18565                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18566                    // Once the internal notion of the active user has switched, we lock the device
18567                    // with the option to show the user switcher on the keyguard.
18568                    mWindowManager.lockNow(null);
18569                } else {
18570                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18571                    updateCurrentProfileIdsLocked();
18572                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18573                    mUserLru.remove(currentUserIdInt);
18574                    mUserLru.add(currentUserIdInt);
18575                }
18576
18577                final UserStartedState uss = mStartedUsers.get(userId);
18578
18579                // Make sure user is in the started state.  If it is currently
18580                // stopping, we need to knock that off.
18581                if (uss.mState == UserStartedState.STATE_STOPPING) {
18582                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18583                    // so we can just fairly silently bring the user back from
18584                    // the almost-dead.
18585                    uss.mState = UserStartedState.STATE_RUNNING;
18586                    updateStartedUserArrayLocked();
18587                    needStart = true;
18588                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18589                    // This means ACTION_SHUTDOWN has been sent, so we will
18590                    // need to treat this as a new boot of the user.
18591                    uss.mState = UserStartedState.STATE_BOOTING;
18592                    updateStartedUserArrayLocked();
18593                    needStart = true;
18594                }
18595
18596                if (uss.mState == UserStartedState.STATE_BOOTING) {
18597                    // Booting up a new user, need to tell system services about it.
18598                    // Note that this is on the same handler as scheduling of broadcasts,
18599                    // which is important because it needs to go first.
18600                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18601                }
18602
18603                if (foreground) {
18604                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18605                            oldUserId));
18606                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18607                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18608                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18609                            oldUserId, userId, uss));
18610                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18611                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18612                }
18613
18614                if (needStart) {
18615                    // Send USER_STARTED broadcast
18616                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18617                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18618                            | Intent.FLAG_RECEIVER_FOREGROUND);
18619                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18620                    broadcastIntentLocked(null, null, intent,
18621                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18622                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18623                }
18624
18625                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18626                    if (userId != UserHandle.USER_OWNER) {
18627                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18628                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18629                        broadcastIntentLocked(null, null, intent, null,
18630                                new IIntentReceiver.Stub() {
18631                                    public void performReceive(Intent intent, int resultCode,
18632                                            String data, Bundle extras, boolean ordered,
18633                                            boolean sticky, int sendingUser) {
18634                                        onUserInitialized(uss, foreground, oldUserId, userId);
18635                                    }
18636                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18637                                true, false, MY_PID, Process.SYSTEM_UID,
18638                                userId);
18639                        uss.initializing = true;
18640                    } else {
18641                        getUserManagerLocked().makeInitialized(userInfo.id);
18642                    }
18643                }
18644
18645                if (foreground) {
18646                    if (!uss.initializing) {
18647                        moveUserToForeground(uss, oldUserId, userId);
18648                    }
18649                } else {
18650                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18651                }
18652
18653                if (needStart) {
18654                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18655                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18656                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18657                    broadcastIntentLocked(null, null, intent,
18658                            null, new IIntentReceiver.Stub() {
18659                                @Override
18660                                public void performReceive(Intent intent, int resultCode, String data,
18661                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18662                                        throws RemoteException {
18663                                }
18664                            }, 0, null, null,
18665                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18666                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18667                }
18668            }
18669        } finally {
18670            Binder.restoreCallingIdentity(ident);
18671        }
18672
18673        return true;
18674    }
18675
18676    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18677        long ident = Binder.clearCallingIdentity();
18678        try {
18679            Intent intent;
18680            if (oldUserId >= 0) {
18681                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18682                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18683                int count = profiles.size();
18684                for (int i = 0; i < count; i++) {
18685                    int profileUserId = profiles.get(i).id;
18686                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18687                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18688                            | Intent.FLAG_RECEIVER_FOREGROUND);
18689                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18690                    broadcastIntentLocked(null, null, intent,
18691                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18692                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18693                }
18694            }
18695            if (newUserId >= 0) {
18696                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18697                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18698                int count = profiles.size();
18699                for (int i = 0; i < count; i++) {
18700                    int profileUserId = profiles.get(i).id;
18701                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18702                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18703                            | Intent.FLAG_RECEIVER_FOREGROUND);
18704                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18705                    broadcastIntentLocked(null, null, intent,
18706                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18707                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18708                }
18709                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18710                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18711                        | Intent.FLAG_RECEIVER_FOREGROUND);
18712                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18713                broadcastIntentLocked(null, null, intent,
18714                        null, null, 0, null, null,
18715                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18716                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18717            }
18718        } finally {
18719            Binder.restoreCallingIdentity(ident);
18720        }
18721    }
18722
18723    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18724            final int newUserId) {
18725        final int N = mUserSwitchObservers.beginBroadcast();
18726        if (N > 0) {
18727            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18728                int mCount = 0;
18729                @Override
18730                public void sendResult(Bundle data) throws RemoteException {
18731                    synchronized (ActivityManagerService.this) {
18732                        if (mCurUserSwitchCallback == this) {
18733                            mCount++;
18734                            if (mCount == N) {
18735                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18736                            }
18737                        }
18738                    }
18739                }
18740            };
18741            synchronized (this) {
18742                uss.switching = true;
18743                mCurUserSwitchCallback = callback;
18744            }
18745            for (int i=0; i<N; i++) {
18746                try {
18747                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18748                            newUserId, callback);
18749                } catch (RemoteException e) {
18750                }
18751            }
18752        } else {
18753            synchronized (this) {
18754                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18755            }
18756        }
18757        mUserSwitchObservers.finishBroadcast();
18758    }
18759
18760    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18761        synchronized (this) {
18762            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18763            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18764        }
18765    }
18766
18767    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18768        mCurUserSwitchCallback = null;
18769        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18770        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18771                oldUserId, newUserId, uss));
18772    }
18773
18774    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18775        synchronized (this) {
18776            if (foreground) {
18777                moveUserToForeground(uss, oldUserId, newUserId);
18778            }
18779        }
18780
18781        completeSwitchAndInitalize(uss, newUserId, true, false);
18782    }
18783
18784    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18785        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18786        if (homeInFront) {
18787            startHomeActivityLocked(newUserId);
18788        } else {
18789            mStackSupervisor.resumeTopActivitiesLocked();
18790        }
18791        EventLogTags.writeAmSwitchUser(newUserId);
18792        getUserManagerLocked().userForeground(newUserId);
18793        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18794    }
18795
18796    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18797        completeSwitchAndInitalize(uss, newUserId, false, true);
18798    }
18799
18800    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18801            boolean clearInitializing, boolean clearSwitching) {
18802        boolean unfrozen = false;
18803        synchronized (this) {
18804            if (clearInitializing) {
18805                uss.initializing = false;
18806                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18807            }
18808            if (clearSwitching) {
18809                uss.switching = false;
18810            }
18811            if (!uss.switching && !uss.initializing) {
18812                mWindowManager.stopFreezingScreen();
18813                unfrozen = true;
18814            }
18815        }
18816        if (unfrozen) {
18817            final int N = mUserSwitchObservers.beginBroadcast();
18818            for (int i=0; i<N; i++) {
18819                try {
18820                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18821                } catch (RemoteException e) {
18822                }
18823            }
18824            mUserSwitchObservers.finishBroadcast();
18825        }
18826    }
18827
18828    void scheduleStartProfilesLocked() {
18829        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18830            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18831                    DateUtils.SECOND_IN_MILLIS);
18832        }
18833    }
18834
18835    void startProfilesLocked() {
18836        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18837        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18838                mCurrentUserId, false /* enabledOnly */);
18839        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18840        for (UserInfo user : profiles) {
18841            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18842                    && user.id != mCurrentUserId) {
18843                toStart.add(user);
18844            }
18845        }
18846        final int n = toStart.size();
18847        int i = 0;
18848        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18849            startUserInBackground(toStart.get(i).id);
18850        }
18851        if (i < n) {
18852            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18853        }
18854    }
18855
18856    void finishUserBoot(UserStartedState uss) {
18857        synchronized (this) {
18858            if (uss.mState == UserStartedState.STATE_BOOTING
18859                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18860                uss.mState = UserStartedState.STATE_RUNNING;
18861                final int userId = uss.mHandle.getIdentifier();
18862                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18863                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18864                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18865                broadcastIntentLocked(null, null, intent,
18866                        null, null, 0, null, null,
18867                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18868                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18869            }
18870        }
18871    }
18872
18873    void finishUserSwitch(UserStartedState uss) {
18874        synchronized (this) {
18875            finishUserBoot(uss);
18876
18877            startProfilesLocked();
18878
18879            int num = mUserLru.size();
18880            int i = 0;
18881            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18882                Integer oldUserId = mUserLru.get(i);
18883                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18884                if (oldUss == null) {
18885                    // Shouldn't happen, but be sane if it does.
18886                    mUserLru.remove(i);
18887                    num--;
18888                    continue;
18889                }
18890                if (oldUss.mState == UserStartedState.STATE_STOPPING
18891                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18892                    // This user is already stopping, doesn't count.
18893                    num--;
18894                    i++;
18895                    continue;
18896                }
18897                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18898                    // Owner and current can't be stopped, but count as running.
18899                    i++;
18900                    continue;
18901                }
18902                // This is a user to be stopped.
18903                stopUserLocked(oldUserId, null);
18904                num--;
18905                i++;
18906            }
18907        }
18908    }
18909
18910    @Override
18911    public int stopUser(final int userId, final IStopUserCallback callback) {
18912        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18913                != PackageManager.PERMISSION_GRANTED) {
18914            String msg = "Permission Denial: switchUser() from pid="
18915                    + Binder.getCallingPid()
18916                    + ", uid=" + Binder.getCallingUid()
18917                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18918            Slog.w(TAG, msg);
18919            throw new SecurityException(msg);
18920        }
18921        if (userId <= 0) {
18922            throw new IllegalArgumentException("Can't stop primary user " + userId);
18923        }
18924        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18925        synchronized (this) {
18926            return stopUserLocked(userId, callback);
18927        }
18928    }
18929
18930    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18931        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18932        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18933            return ActivityManager.USER_OP_IS_CURRENT;
18934        }
18935
18936        final UserStartedState uss = mStartedUsers.get(userId);
18937        if (uss == null) {
18938            // User is not started, nothing to do...  but we do need to
18939            // callback if requested.
18940            if (callback != null) {
18941                mHandler.post(new Runnable() {
18942                    @Override
18943                    public void run() {
18944                        try {
18945                            callback.userStopped(userId);
18946                        } catch (RemoteException e) {
18947                        }
18948                    }
18949                });
18950            }
18951            return ActivityManager.USER_OP_SUCCESS;
18952        }
18953
18954        if (callback != null) {
18955            uss.mStopCallbacks.add(callback);
18956        }
18957
18958        if (uss.mState != UserStartedState.STATE_STOPPING
18959                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18960            uss.mState = UserStartedState.STATE_STOPPING;
18961            updateStartedUserArrayLocked();
18962
18963            long ident = Binder.clearCallingIdentity();
18964            try {
18965                // We are going to broadcast ACTION_USER_STOPPING and then
18966                // once that is done send a final ACTION_SHUTDOWN and then
18967                // stop the user.
18968                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18969                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18970                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18971                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18972                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18973                // This is the result receiver for the final shutdown broadcast.
18974                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18975                    @Override
18976                    public void performReceive(Intent intent, int resultCode, String data,
18977                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18978                        finishUserStop(uss);
18979                    }
18980                };
18981                // This is the result receiver for the initial stopping broadcast.
18982                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18983                    @Override
18984                    public void performReceive(Intent intent, int resultCode, String data,
18985                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18986                        // On to the next.
18987                        synchronized (ActivityManagerService.this) {
18988                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18989                                // Whoops, we are being started back up.  Abort, abort!
18990                                return;
18991                            }
18992                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18993                        }
18994                        mBatteryStatsService.noteEvent(
18995                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18996                                Integer.toString(userId), userId);
18997                        mSystemServiceManager.stopUser(userId);
18998                        broadcastIntentLocked(null, null, shutdownIntent,
18999                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19000                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19001                    }
19002                };
19003                // Kick things off.
19004                broadcastIntentLocked(null, null, stoppingIntent,
19005                        null, stoppingReceiver, 0, null, null,
19006                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19007                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19008            } finally {
19009                Binder.restoreCallingIdentity(ident);
19010            }
19011        }
19012
19013        return ActivityManager.USER_OP_SUCCESS;
19014    }
19015
19016    void finishUserStop(UserStartedState uss) {
19017        final int userId = uss.mHandle.getIdentifier();
19018        boolean stopped;
19019        ArrayList<IStopUserCallback> callbacks;
19020        synchronized (this) {
19021            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19022            if (mStartedUsers.get(userId) != uss) {
19023                stopped = false;
19024            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19025                stopped = false;
19026            } else {
19027                stopped = true;
19028                // User can no longer run.
19029                mStartedUsers.remove(userId);
19030                mUserLru.remove(Integer.valueOf(userId));
19031                updateStartedUserArrayLocked();
19032
19033                // Clean up all state and processes associated with the user.
19034                // Kill all the processes for the user.
19035                forceStopUserLocked(userId, "finish user");
19036            }
19037
19038            // Explicitly remove the old information in mRecentTasks.
19039            removeRecentTasksForUserLocked(userId);
19040        }
19041
19042        for (int i=0; i<callbacks.size(); i++) {
19043            try {
19044                if (stopped) callbacks.get(i).userStopped(userId);
19045                else callbacks.get(i).userStopAborted(userId);
19046            } catch (RemoteException e) {
19047            }
19048        }
19049
19050        if (stopped) {
19051            mSystemServiceManager.cleanupUser(userId);
19052            synchronized (this) {
19053                mStackSupervisor.removeUserLocked(userId);
19054            }
19055        }
19056    }
19057
19058    @Override
19059    public UserInfo getCurrentUser() {
19060        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19061                != PackageManager.PERMISSION_GRANTED) && (
19062                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19063                != PackageManager.PERMISSION_GRANTED)) {
19064            String msg = "Permission Denial: getCurrentUser() from pid="
19065                    + Binder.getCallingPid()
19066                    + ", uid=" + Binder.getCallingUid()
19067                    + " requires " + INTERACT_ACROSS_USERS;
19068            Slog.w(TAG, msg);
19069            throw new SecurityException(msg);
19070        }
19071        synchronized (this) {
19072            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19073            return getUserManagerLocked().getUserInfo(userId);
19074        }
19075    }
19076
19077    int getCurrentUserIdLocked() {
19078        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19079    }
19080
19081    @Override
19082    public boolean isUserRunning(int userId, boolean orStopped) {
19083        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19084                != PackageManager.PERMISSION_GRANTED) {
19085            String msg = "Permission Denial: isUserRunning() from pid="
19086                    + Binder.getCallingPid()
19087                    + ", uid=" + Binder.getCallingUid()
19088                    + " requires " + INTERACT_ACROSS_USERS;
19089            Slog.w(TAG, msg);
19090            throw new SecurityException(msg);
19091        }
19092        synchronized (this) {
19093            return isUserRunningLocked(userId, orStopped);
19094        }
19095    }
19096
19097    boolean isUserRunningLocked(int userId, boolean orStopped) {
19098        UserStartedState state = mStartedUsers.get(userId);
19099        if (state == null) {
19100            return false;
19101        }
19102        if (orStopped) {
19103            return true;
19104        }
19105        return state.mState != UserStartedState.STATE_STOPPING
19106                && state.mState != UserStartedState.STATE_SHUTDOWN;
19107    }
19108
19109    @Override
19110    public int[] getRunningUserIds() {
19111        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19112                != PackageManager.PERMISSION_GRANTED) {
19113            String msg = "Permission Denial: isUserRunning() from pid="
19114                    + Binder.getCallingPid()
19115                    + ", uid=" + Binder.getCallingUid()
19116                    + " requires " + INTERACT_ACROSS_USERS;
19117            Slog.w(TAG, msg);
19118            throw new SecurityException(msg);
19119        }
19120        synchronized (this) {
19121            return mStartedUserArray;
19122        }
19123    }
19124
19125    private void updateStartedUserArrayLocked() {
19126        int num = 0;
19127        for (int i=0; i<mStartedUsers.size();  i++) {
19128            UserStartedState uss = mStartedUsers.valueAt(i);
19129            // This list does not include stopping users.
19130            if (uss.mState != UserStartedState.STATE_STOPPING
19131                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19132                num++;
19133            }
19134        }
19135        mStartedUserArray = new int[num];
19136        num = 0;
19137        for (int i=0; i<mStartedUsers.size();  i++) {
19138            UserStartedState uss = mStartedUsers.valueAt(i);
19139            if (uss.mState != UserStartedState.STATE_STOPPING
19140                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19141                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19142                num++;
19143            }
19144        }
19145    }
19146
19147    @Override
19148    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19149        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19150                != PackageManager.PERMISSION_GRANTED) {
19151            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19152                    + Binder.getCallingPid()
19153                    + ", uid=" + Binder.getCallingUid()
19154                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19155            Slog.w(TAG, msg);
19156            throw new SecurityException(msg);
19157        }
19158
19159        mUserSwitchObservers.register(observer);
19160    }
19161
19162    @Override
19163    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19164        mUserSwitchObservers.unregister(observer);
19165    }
19166
19167    private boolean userExists(int userId) {
19168        if (userId == 0) {
19169            return true;
19170        }
19171        UserManagerService ums = getUserManagerLocked();
19172        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19173    }
19174
19175    int[] getUsersLocked() {
19176        UserManagerService ums = getUserManagerLocked();
19177        return ums != null ? ums.getUserIds() : new int[] { 0 };
19178    }
19179
19180    UserManagerService getUserManagerLocked() {
19181        if (mUserManager == null) {
19182            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19183            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19184        }
19185        return mUserManager;
19186    }
19187
19188    private int applyUserId(int uid, int userId) {
19189        return UserHandle.getUid(userId, uid);
19190    }
19191
19192    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19193        if (info == null) return null;
19194        ApplicationInfo newInfo = new ApplicationInfo(info);
19195        newInfo.uid = applyUserId(info.uid, userId);
19196        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19197                + info.packageName;
19198        return newInfo;
19199    }
19200
19201    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19202        if (aInfo == null
19203                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19204            return aInfo;
19205        }
19206
19207        ActivityInfo info = new ActivityInfo(aInfo);
19208        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19209        return info;
19210    }
19211
19212    private final class LocalService extends ActivityManagerInternal {
19213        @Override
19214        public void goingToSleep() {
19215            ActivityManagerService.this.goingToSleep();
19216        }
19217
19218        @Override
19219        public void wakingUp() {
19220            ActivityManagerService.this.wakingUp();
19221        }
19222
19223        @Override
19224        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19225                String processName, String abiOverride, int uid, Runnable crashHandler) {
19226            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19227                    processName, abiOverride, uid, crashHandler);
19228        }
19229    }
19230
19231    /**
19232     * An implementation of IAppTask, that allows an app to manage its own tasks via
19233     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19234     * only the process that calls getAppTasks() can call the AppTask methods.
19235     */
19236    class AppTaskImpl extends IAppTask.Stub {
19237        private int mTaskId;
19238        private int mCallingUid;
19239
19240        public AppTaskImpl(int taskId, int callingUid) {
19241            mTaskId = taskId;
19242            mCallingUid = callingUid;
19243        }
19244
19245        private void checkCaller() {
19246            if (mCallingUid != Binder.getCallingUid()) {
19247                throw new SecurityException("Caller " + mCallingUid
19248                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19249            }
19250        }
19251
19252        @Override
19253        public void finishAndRemoveTask() {
19254            checkCaller();
19255
19256            synchronized (ActivityManagerService.this) {
19257                long origId = Binder.clearCallingIdentity();
19258                try {
19259                    if (!removeTaskByIdLocked(mTaskId, false)) {
19260                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19261                    }
19262                } finally {
19263                    Binder.restoreCallingIdentity(origId);
19264                }
19265            }
19266        }
19267
19268        @Override
19269        public ActivityManager.RecentTaskInfo getTaskInfo() {
19270            checkCaller();
19271
19272            synchronized (ActivityManagerService.this) {
19273                long origId = Binder.clearCallingIdentity();
19274                try {
19275                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19276                    if (tr == null) {
19277                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19278                    }
19279                    return createRecentTaskInfoFromTaskRecord(tr);
19280                } finally {
19281                    Binder.restoreCallingIdentity(origId);
19282                }
19283            }
19284        }
19285
19286        @Override
19287        public void moveToFront() {
19288            checkCaller();
19289
19290            final TaskRecord tr;
19291            synchronized (ActivityManagerService.this) {
19292                tr = recentTaskForIdLocked(mTaskId);
19293                if (tr == null) {
19294                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19295                }
19296                if (tr.getRootActivity() != null) {
19297                    moveTaskToFrontLocked(tr.taskId, 0, null);
19298                    return;
19299                }
19300            }
19301
19302            startActivityFromRecentsInner(tr.taskId, null);
19303        }
19304
19305        @Override
19306        public int startActivity(IBinder whoThread, String callingPackage,
19307                Intent intent, String resolvedType, Bundle options) {
19308            checkCaller();
19309
19310            int callingUser = UserHandle.getCallingUserId();
19311            TaskRecord tr;
19312            IApplicationThread appThread;
19313            synchronized (ActivityManagerService.this) {
19314                tr = recentTaskForIdLocked(mTaskId);
19315                if (tr == null) {
19316                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19317                }
19318                appThread = ApplicationThreadNative.asInterface(whoThread);
19319                if (appThread == null) {
19320                    throw new IllegalArgumentException("Bad app thread " + appThread);
19321                }
19322            }
19323            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19324                    resolvedType, null, null, null, null, 0, 0, null, null,
19325                    null, options, callingUser, null, tr);
19326        }
19327
19328        @Override
19329        public void setExcludeFromRecents(boolean exclude) {
19330            checkCaller();
19331
19332            synchronized (ActivityManagerService.this) {
19333                long origId = Binder.clearCallingIdentity();
19334                try {
19335                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19336                    if (tr == null) {
19337                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19338                    }
19339                    Intent intent = tr.getBaseIntent();
19340                    if (exclude) {
19341                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19342                    } else {
19343                        intent.setFlags(intent.getFlags()
19344                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19345                    }
19346                } finally {
19347                    Binder.restoreCallingIdentity(origId);
19348                }
19349            }
19350        }
19351    }
19352}
19353