ActivityManagerService.java revision 76a748e62f354c799342044f724e1f4b80121837
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 IM_FEELING_LUCKY_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
1216    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1217    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1218    static final int FIRST_COMPAT_MODE_MSG = 300;
1219    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1220
1221    AlertDialog mUidAlert;
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                String title = "System UIDs Inconsistent";
1451                String text = "UIDs on the system are inconsistent, you need to wipe your"
1452                        + " data partition or your device will be unstable.";
1453                Log.e(TAG, title + ": " + text);
1454                if (mShowDialogs) {
1455                    // XXX This is a temporary dialog, no need to localize.
1456                    AlertDialog d = new BaseErrorDialog(mContext);
1457                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1458                    d.setCancelable(false);
1459                    d.setTitle(title);
1460                    d.setMessage(text);
1461                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1462                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1463                    mUidAlert = d;
1464                    d.show();
1465                }
1466            } break;
1467            case IM_FEELING_LUCKY_MSG: {
1468                if (mUidAlert != null) {
1469                    mUidAlert.dismiss();
1470                    mUidAlert = null;
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            }
1731        }
1732    };
1733
1734    static final int COLLECT_PSS_BG_MSG = 1;
1735
1736    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1737        @Override
1738        public void handleMessage(Message msg) {
1739            switch (msg.what) {
1740            case COLLECT_PSS_BG_MSG: {
1741                long start = SystemClock.uptimeMillis();
1742                MemInfoReader memInfo = null;
1743                synchronized (ActivityManagerService.this) {
1744                    if (mFullPssPending) {
1745                        mFullPssPending = false;
1746                        memInfo = new MemInfoReader();
1747                    }
1748                }
1749                if (memInfo != null) {
1750                    updateCpuStatsNow();
1751                    long nativeTotalPss = 0;
1752                    synchronized (mProcessCpuTracker) {
1753                        final int N = mProcessCpuTracker.countStats();
1754                        for (int j=0; j<N; j++) {
1755                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1756                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1757                                // This is definitely an application process; skip it.
1758                                continue;
1759                            }
1760                            synchronized (mPidsSelfLocked) {
1761                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1762                                    // This is one of our own processes; skip it.
1763                                    continue;
1764                                }
1765                            }
1766                            nativeTotalPss += Debug.getPss(st.pid, null);
1767                        }
1768                    }
1769                    memInfo.readMemInfo();
1770                    synchronized (ActivityManagerService.this) {
1771                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1772                                + (SystemClock.uptimeMillis()-start) + "ms");
1773                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1774                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1775                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1776                    }
1777                }
1778
1779                int i=0, num=0;
1780                long[] tmp = new long[1];
1781                do {
1782                    ProcessRecord proc;
1783                    int procState;
1784                    int pid;
1785                    synchronized (ActivityManagerService.this) {
1786                        if (i >= mPendingPssProcesses.size()) {
1787                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1788                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1789                            mPendingPssProcesses.clear();
1790                            return;
1791                        }
1792                        proc = mPendingPssProcesses.get(i);
1793                        procState = proc.pssProcState;
1794                        if (proc.thread != null && procState == proc.setProcState) {
1795                            pid = proc.pid;
1796                        } else {
1797                            proc = null;
1798                            pid = 0;
1799                        }
1800                        i++;
1801                    }
1802                    if (proc != null) {
1803                        long pss = Debug.getPss(pid, tmp);
1804                        synchronized (ActivityManagerService.this) {
1805                            if (proc.thread != null && proc.setProcState == procState
1806                                    && proc.pid == pid) {
1807                                num++;
1808                                proc.lastPssTime = SystemClock.uptimeMillis();
1809                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1810                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1811                                        + ": " + pss + " lastPss=" + proc.lastPss
1812                                        + " state=" + ProcessList.makeProcStateString(procState));
1813                                if (proc.initialIdlePss == 0) {
1814                                    proc.initialIdlePss = pss;
1815                                }
1816                                proc.lastPss = pss;
1817                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1818                                    proc.lastCachedPss = pss;
1819                                }
1820                            }
1821                        }
1822                    }
1823                } while (true);
1824            }
1825            }
1826        }
1827    };
1828
1829    /**
1830     * Monitor for package changes and update our internal state.
1831     */
1832    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1833        @Override
1834        public void onPackageRemoved(String packageName, int uid) {
1835            // Remove all tasks with activities in the specified package from the list of recent tasks
1836            final int eventUserId = getChangingUserId();
1837            synchronized (ActivityManagerService.this) {
1838                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1839                    TaskRecord tr = mRecentTasks.get(i);
1840                    if (tr.userId != eventUserId) continue;
1841
1842                    ComponentName cn = tr.intent.getComponent();
1843                    if (cn != null && cn.getPackageName().equals(packageName)) {
1844                        // If the package name matches, remove the task
1845                        removeTaskByIdLocked(tr.taskId, true);
1846                    }
1847                }
1848            }
1849        }
1850
1851        @Override
1852        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1853            onPackageModified(packageName);
1854            return true;
1855        }
1856
1857        @Override
1858        public void onPackageModified(String packageName) {
1859            final int eventUserId = getChangingUserId();
1860            final IPackageManager pm = AppGlobals.getPackageManager();
1861            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1862                    new ArrayList<Pair<Intent, Integer>>();
1863            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
1864            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1865            // Copy the list of recent tasks so that we don't hold onto the lock on
1866            // ActivityManagerService for long periods while checking if components exist.
1867            synchronized (ActivityManagerService.this) {
1868                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1869                    TaskRecord tr = mRecentTasks.get(i);
1870                    if (tr.userId != eventUserId) continue;
1871
1872                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1873                }
1874            }
1875            // Check the recent tasks and filter out all tasks with components that no longer exist.
1876            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1877                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1878                ComponentName cn = p.first.getComponent();
1879                if (cn != null && cn.getPackageName().equals(packageName)) {
1880                    if (componentsKnownToExist.contains(cn)) {
1881                        // If we know that the component still exists in the package, then skip
1882                        continue;
1883                    }
1884                    try {
1885                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
1886                        if (info != null) {
1887                            componentsKnownToExist.add(cn);
1888                        } else {
1889                            tasksToRemove.add(p.second);
1890                        }
1891                    } catch (RemoteException e) {
1892                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
1893                    }
1894                }
1895            }
1896            // Prune all the tasks with removed components from the list of recent tasks
1897            synchronized (ActivityManagerService.this) {
1898                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1899                    removeTaskByIdLocked(tasksToRemove.get(i), false);
1900                }
1901            }
1902        }
1903
1904        @Override
1905        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1906            // Force stop the specified packages
1907            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
1908            if (packages != null) {
1909                for (String pkg : packages) {
1910                    synchronized (ActivityManagerService.this) {
1911                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
1912                                userId, "finished booting")) {
1913                            return true;
1914                        }
1915                    }
1916                }
1917            }
1918            return false;
1919        }
1920    };
1921
1922    public void setSystemProcess() {
1923        try {
1924            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1925            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1926            ServiceManager.addService("meminfo", new MemBinder(this));
1927            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1928            ServiceManager.addService("dbinfo", new DbBinder(this));
1929            if (MONITOR_CPU_USAGE) {
1930                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1931            }
1932            ServiceManager.addService("permission", new PermissionController(this));
1933
1934            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1935                    "android", STOCK_PM_FLAGS);
1936            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1937
1938            synchronized (this) {
1939                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1940                app.persistent = true;
1941                app.pid = MY_PID;
1942                app.maxAdj = ProcessList.SYSTEM_ADJ;
1943                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1944                mProcessNames.put(app.processName, app.uid, app);
1945                synchronized (mPidsSelfLocked) {
1946                    mPidsSelfLocked.put(app.pid, app);
1947                }
1948                updateLruProcessLocked(app, false, null);
1949                updateOomAdjLocked();
1950            }
1951        } catch (PackageManager.NameNotFoundException e) {
1952            throw new RuntimeException(
1953                    "Unable to find android system package", e);
1954        }
1955    }
1956
1957    public void setWindowManager(WindowManagerService wm) {
1958        mWindowManager = wm;
1959        mStackSupervisor.setWindowManager(wm);
1960    }
1961
1962    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1963        mUsageStatsService = usageStatsManager;
1964    }
1965
1966    public void startObservingNativeCrashes() {
1967        final NativeCrashListener ncl = new NativeCrashListener(this);
1968        ncl.start();
1969    }
1970
1971    public IAppOpsService getAppOpsService() {
1972        return mAppOpsService;
1973    }
1974
1975    static class MemBinder extends Binder {
1976        ActivityManagerService mActivityManagerService;
1977        MemBinder(ActivityManagerService activityManagerService) {
1978            mActivityManagerService = activityManagerService;
1979        }
1980
1981        @Override
1982        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1983            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1984                    != PackageManager.PERMISSION_GRANTED) {
1985                pw.println("Permission Denial: can't dump meminfo from from pid="
1986                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1987                        + " without permission " + android.Manifest.permission.DUMP);
1988                return;
1989            }
1990
1991            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1992        }
1993    }
1994
1995    static class GraphicsBinder extends Binder {
1996        ActivityManagerService mActivityManagerService;
1997        GraphicsBinder(ActivityManagerService activityManagerService) {
1998            mActivityManagerService = activityManagerService;
1999        }
2000
2001        @Override
2002        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2003            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2004                    != PackageManager.PERMISSION_GRANTED) {
2005                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2006                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2007                        + " without permission " + android.Manifest.permission.DUMP);
2008                return;
2009            }
2010
2011            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2012        }
2013    }
2014
2015    static class DbBinder extends Binder {
2016        ActivityManagerService mActivityManagerService;
2017        DbBinder(ActivityManagerService activityManagerService) {
2018            mActivityManagerService = activityManagerService;
2019        }
2020
2021        @Override
2022        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2023            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2024                    != PackageManager.PERMISSION_GRANTED) {
2025                pw.println("Permission Denial: can't dump dbinfo from from pid="
2026                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2027                        + " without permission " + android.Manifest.permission.DUMP);
2028                return;
2029            }
2030
2031            mActivityManagerService.dumpDbInfo(fd, pw, args);
2032        }
2033    }
2034
2035    static class CpuBinder extends Binder {
2036        ActivityManagerService mActivityManagerService;
2037        CpuBinder(ActivityManagerService activityManagerService) {
2038            mActivityManagerService = activityManagerService;
2039        }
2040
2041        @Override
2042        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2043            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2044                    != PackageManager.PERMISSION_GRANTED) {
2045                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2046                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2047                        + " without permission " + android.Manifest.permission.DUMP);
2048                return;
2049            }
2050
2051            synchronized (mActivityManagerService.mProcessCpuTracker) {
2052                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2053                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2054                        SystemClock.uptimeMillis()));
2055            }
2056        }
2057    }
2058
2059    public static final class Lifecycle extends SystemService {
2060        private final ActivityManagerService mService;
2061
2062        public Lifecycle(Context context) {
2063            super(context);
2064            mService = new ActivityManagerService(context);
2065        }
2066
2067        @Override
2068        public void onStart() {
2069            mService.start();
2070        }
2071
2072        public ActivityManagerService getService() {
2073            return mService;
2074        }
2075    }
2076
2077    // Note: This method is invoked on the main thread but may need to attach various
2078    // handlers to other threads.  So take care to be explicit about the looper.
2079    public ActivityManagerService(Context systemContext) {
2080        mContext = systemContext;
2081        mFactoryTest = FactoryTest.getMode();
2082        mSystemThread = ActivityThread.currentActivityThread();
2083
2084        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2085
2086        mHandlerThread = new ServiceThread(TAG,
2087                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2088        mHandlerThread.start();
2089        mHandler = new MainHandler(mHandlerThread.getLooper());
2090
2091        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2092                "foreground", BROADCAST_FG_TIMEOUT, false);
2093        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2094                "background", BROADCAST_BG_TIMEOUT, true);
2095        mBroadcastQueues[0] = mFgBroadcastQueue;
2096        mBroadcastQueues[1] = mBgBroadcastQueue;
2097
2098        mServices = new ActiveServices(this);
2099        mProviderMap = new ProviderMap(this);
2100
2101        // TODO: Move creation of battery stats service outside of activity manager service.
2102        File dataDir = Environment.getDataDirectory();
2103        File systemDir = new File(dataDir, "system");
2104        systemDir.mkdirs();
2105        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2106        mBatteryStatsService.getActiveStatistics().readLocked();
2107        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2108        mOnBattery = DEBUG_POWER ? true
2109                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2110        mBatteryStatsService.getActiveStatistics().setCallback(this);
2111
2112        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2113
2114        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2115
2116        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2117
2118        // User 0 is the first and only user that runs at boot.
2119        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2120        mUserLru.add(Integer.valueOf(0));
2121        updateStartedUserArrayLocked();
2122
2123        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2124            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2125
2126        mConfiguration.setToDefaults();
2127        mConfiguration.setLocale(Locale.getDefault());
2128
2129        mConfigurationSeq = mConfiguration.seq = 1;
2130        mProcessCpuTracker.init();
2131
2132        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2133        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2134        mStackSupervisor = new ActivityStackSupervisor(this);
2135        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2136
2137        mProcessCpuThread = new Thread("CpuTracker") {
2138            @Override
2139            public void run() {
2140                while (true) {
2141                    try {
2142                        try {
2143                            synchronized(this) {
2144                                final long now = SystemClock.uptimeMillis();
2145                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2146                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2147                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2148                                //        + ", write delay=" + nextWriteDelay);
2149                                if (nextWriteDelay < nextCpuDelay) {
2150                                    nextCpuDelay = nextWriteDelay;
2151                                }
2152                                if (nextCpuDelay > 0) {
2153                                    mProcessCpuMutexFree.set(true);
2154                                    this.wait(nextCpuDelay);
2155                                }
2156                            }
2157                        } catch (InterruptedException e) {
2158                        }
2159                        updateCpuStatsNow();
2160                    } catch (Exception e) {
2161                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2162                    }
2163                }
2164            }
2165        };
2166
2167        Watchdog.getInstance().addMonitor(this);
2168        Watchdog.getInstance().addThread(mHandler);
2169    }
2170
2171    public void setSystemServiceManager(SystemServiceManager mgr) {
2172        mSystemServiceManager = mgr;
2173    }
2174
2175    public void setInstaller(Installer installer) {
2176        mInstaller = installer;
2177    }
2178
2179    private void start() {
2180        Process.removeAllProcessGroups();
2181        mProcessCpuThread.start();
2182
2183        mBatteryStatsService.publish(mContext);
2184        mAppOpsService.publish(mContext);
2185        Slog.d("AppOps", "AppOpsService published");
2186        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2187    }
2188
2189    public void initPowerManagement() {
2190        mStackSupervisor.initPowerManagement();
2191        mBatteryStatsService.initPowerManagement();
2192    }
2193
2194    @Override
2195    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2196            throws RemoteException {
2197        if (code == SYSPROPS_TRANSACTION) {
2198            // We need to tell all apps about the system property change.
2199            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2200            synchronized(this) {
2201                final int NP = mProcessNames.getMap().size();
2202                for (int ip=0; ip<NP; ip++) {
2203                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2204                    final int NA = apps.size();
2205                    for (int ia=0; ia<NA; ia++) {
2206                        ProcessRecord app = apps.valueAt(ia);
2207                        if (app.thread != null) {
2208                            procs.add(app.thread.asBinder());
2209                        }
2210                    }
2211                }
2212            }
2213
2214            int N = procs.size();
2215            for (int i=0; i<N; i++) {
2216                Parcel data2 = Parcel.obtain();
2217                try {
2218                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2219                } catch (RemoteException e) {
2220                }
2221                data2.recycle();
2222            }
2223        }
2224        try {
2225            return super.onTransact(code, data, reply, flags);
2226        } catch (RuntimeException e) {
2227            // The activity manager only throws security exceptions, so let's
2228            // log all others.
2229            if (!(e instanceof SecurityException)) {
2230                Slog.wtf(TAG, "Activity Manager Crash", e);
2231            }
2232            throw e;
2233        }
2234    }
2235
2236    void updateCpuStats() {
2237        final long now = SystemClock.uptimeMillis();
2238        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2239            return;
2240        }
2241        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2242            synchronized (mProcessCpuThread) {
2243                mProcessCpuThread.notify();
2244            }
2245        }
2246    }
2247
2248    void updateCpuStatsNow() {
2249        synchronized (mProcessCpuTracker) {
2250            mProcessCpuMutexFree.set(false);
2251            final long now = SystemClock.uptimeMillis();
2252            boolean haveNewCpuStats = false;
2253
2254            if (MONITOR_CPU_USAGE &&
2255                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2256                mLastCpuTime.set(now);
2257                haveNewCpuStats = true;
2258                mProcessCpuTracker.update();
2259                //Slog.i(TAG, mProcessCpu.printCurrentState());
2260                //Slog.i(TAG, "Total CPU usage: "
2261                //        + mProcessCpu.getTotalCpuPercent() + "%");
2262
2263                // Slog the cpu usage if the property is set.
2264                if ("true".equals(SystemProperties.get("events.cpu"))) {
2265                    int user = mProcessCpuTracker.getLastUserTime();
2266                    int system = mProcessCpuTracker.getLastSystemTime();
2267                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2268                    int irq = mProcessCpuTracker.getLastIrqTime();
2269                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2270                    int idle = mProcessCpuTracker.getLastIdleTime();
2271
2272                    int total = user + system + iowait + irq + softIrq + idle;
2273                    if (total == 0) total = 1;
2274
2275                    EventLog.writeEvent(EventLogTags.CPU,
2276                            ((user+system+iowait+irq+softIrq) * 100) / total,
2277                            (user * 100) / total,
2278                            (system * 100) / total,
2279                            (iowait * 100) / total,
2280                            (irq * 100) / total,
2281                            (softIrq * 100) / total);
2282                }
2283            }
2284
2285            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2286            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2287            synchronized(bstats) {
2288                synchronized(mPidsSelfLocked) {
2289                    if (haveNewCpuStats) {
2290                        if (mOnBattery) {
2291                            int perc = bstats.startAddingCpuLocked();
2292                            int totalUTime = 0;
2293                            int totalSTime = 0;
2294                            final int N = mProcessCpuTracker.countStats();
2295                            for (int i=0; i<N; i++) {
2296                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2297                                if (!st.working) {
2298                                    continue;
2299                                }
2300                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2301                                int otherUTime = (st.rel_utime*perc)/100;
2302                                int otherSTime = (st.rel_stime*perc)/100;
2303                                totalUTime += otherUTime;
2304                                totalSTime += otherSTime;
2305                                if (pr != null) {
2306                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2307                                    if (ps == null || !ps.isActive()) {
2308                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2309                                                pr.info.uid, pr.processName);
2310                                    }
2311                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2312                                            st.rel_stime-otherSTime);
2313                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2314                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2315                                } else {
2316                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2317                                    if (ps == null || !ps.isActive()) {
2318                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2319                                                bstats.mapUid(st.uid), st.name);
2320                                    }
2321                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2322                                            st.rel_stime-otherSTime);
2323                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2324                                }
2325                            }
2326                            bstats.finishAddingCpuLocked(perc, totalUTime,
2327                                    totalSTime, cpuSpeedTimes);
2328                        }
2329                    }
2330                }
2331
2332                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2333                    mLastWriteTime = now;
2334                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2335                }
2336            }
2337        }
2338    }
2339
2340    @Override
2341    public void batteryNeedsCpuUpdate() {
2342        updateCpuStatsNow();
2343    }
2344
2345    @Override
2346    public void batteryPowerChanged(boolean onBattery) {
2347        // When plugging in, update the CPU stats first before changing
2348        // the plug state.
2349        updateCpuStatsNow();
2350        synchronized (this) {
2351            synchronized(mPidsSelfLocked) {
2352                mOnBattery = DEBUG_POWER ? true : onBattery;
2353            }
2354        }
2355    }
2356
2357    /**
2358     * Initialize the application bind args. These are passed to each
2359     * process when the bindApplication() IPC is sent to the process. They're
2360     * lazily setup to make sure the services are running when they're asked for.
2361     */
2362    private HashMap<String, IBinder> getCommonServicesLocked() {
2363        if (mAppBindArgs == null) {
2364            mAppBindArgs = new HashMap<String, IBinder>();
2365
2366            // Setup the application init args
2367            mAppBindArgs.put("package", ServiceManager.getService("package"));
2368            mAppBindArgs.put("window", ServiceManager.getService("window"));
2369            mAppBindArgs.put(Context.ALARM_SERVICE,
2370                    ServiceManager.getService(Context.ALARM_SERVICE));
2371        }
2372        return mAppBindArgs;
2373    }
2374
2375    final void setFocusedActivityLocked(ActivityRecord r) {
2376        if (mFocusedActivity != r) {
2377            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2378            mFocusedActivity = r;
2379            if (r.task != null && r.task.voiceInteractor != null) {
2380                startRunningVoiceLocked();
2381            } else {
2382                finishRunningVoiceLocked();
2383            }
2384            mStackSupervisor.setFocusedStack(r);
2385            if (r != null) {
2386                mWindowManager.setFocusedApp(r.appToken, true);
2387            }
2388            applyUpdateLockStateLocked(r);
2389        }
2390    }
2391
2392    final void clearFocusedActivity(ActivityRecord r) {
2393        if (mFocusedActivity == r) {
2394            mFocusedActivity = null;
2395        }
2396    }
2397
2398    @Override
2399    public void setFocusedStack(int stackId) {
2400        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2401        synchronized (ActivityManagerService.this) {
2402            ActivityStack stack = mStackSupervisor.getStack(stackId);
2403            if (stack != null) {
2404                ActivityRecord r = stack.topRunningActivityLocked(null);
2405                if (r != null) {
2406                    setFocusedActivityLocked(r);
2407                }
2408            }
2409        }
2410    }
2411
2412    @Override
2413    public void notifyActivityDrawn(IBinder token) {
2414        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2415        synchronized (this) {
2416            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2417            if (r != null) {
2418                r.task.stack.notifyActivityDrawnLocked(r);
2419            }
2420        }
2421    }
2422
2423    final void applyUpdateLockStateLocked(ActivityRecord r) {
2424        // Modifications to the UpdateLock state are done on our handler, outside
2425        // the activity manager's locks.  The new state is determined based on the
2426        // state *now* of the relevant activity record.  The object is passed to
2427        // the handler solely for logging detail, not to be consulted/modified.
2428        final boolean nextState = r != null && r.immersive;
2429        mHandler.sendMessage(
2430                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2431    }
2432
2433    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2434        Message msg = Message.obtain();
2435        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2436        msg.obj = r.task.askedCompatMode ? null : r;
2437        mHandler.sendMessage(msg);
2438    }
2439
2440    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2441            String what, Object obj, ProcessRecord srcApp) {
2442        app.lastActivityTime = now;
2443
2444        if (app.activities.size() > 0) {
2445            // Don't want to touch dependent processes that are hosting activities.
2446            return index;
2447        }
2448
2449        int lrui = mLruProcesses.lastIndexOf(app);
2450        if (lrui < 0) {
2451            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2452                    + what + " " + obj + " from " + srcApp);
2453            return index;
2454        }
2455
2456        if (lrui >= index) {
2457            // Don't want to cause this to move dependent processes *back* in the
2458            // list as if they were less frequently used.
2459            return index;
2460        }
2461
2462        if (lrui >= mLruProcessActivityStart) {
2463            // Don't want to touch dependent processes that are hosting activities.
2464            return index;
2465        }
2466
2467        mLruProcesses.remove(lrui);
2468        if (index > 0) {
2469            index--;
2470        }
2471        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2472                + " in LRU list: " + app);
2473        mLruProcesses.add(index, app);
2474        return index;
2475    }
2476
2477    final void removeLruProcessLocked(ProcessRecord app) {
2478        int lrui = mLruProcesses.lastIndexOf(app);
2479        if (lrui >= 0) {
2480            if (!app.killed) {
2481                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2482                Process.killProcessQuiet(app.pid);
2483                Process.killProcessGroup(app.info.uid, app.pid);
2484            }
2485            if (lrui <= mLruProcessActivityStart) {
2486                mLruProcessActivityStart--;
2487            }
2488            if (lrui <= mLruProcessServiceStart) {
2489                mLruProcessServiceStart--;
2490            }
2491            mLruProcesses.remove(lrui);
2492        }
2493    }
2494
2495    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2496            ProcessRecord client) {
2497        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2498                || app.treatLikeActivity;
2499        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2500        if (!activityChange && hasActivity) {
2501            // The process has activities, so we are only allowing activity-based adjustments
2502            // to move it.  It should be kept in the front of the list with other
2503            // processes that have activities, and we don't want those to change their
2504            // order except due to activity operations.
2505            return;
2506        }
2507
2508        mLruSeq++;
2509        final long now = SystemClock.uptimeMillis();
2510        app.lastActivityTime = now;
2511
2512        // First a quick reject: if the app is already at the position we will
2513        // put it, then there is nothing to do.
2514        if (hasActivity) {
2515            final int N = mLruProcesses.size();
2516            if (N > 0 && mLruProcesses.get(N-1) == app) {
2517                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2518                return;
2519            }
2520        } else {
2521            if (mLruProcessServiceStart > 0
2522                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2523                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2524                return;
2525            }
2526        }
2527
2528        int lrui = mLruProcesses.lastIndexOf(app);
2529
2530        if (app.persistent && lrui >= 0) {
2531            // We don't care about the position of persistent processes, as long as
2532            // they are in the list.
2533            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2534            return;
2535        }
2536
2537        /* In progress: compute new position first, so we can avoid doing work
2538           if the process is not actually going to move.  Not yet working.
2539        int addIndex;
2540        int nextIndex;
2541        boolean inActivity = false, inService = false;
2542        if (hasActivity) {
2543            // Process has activities, put it at the very tipsy-top.
2544            addIndex = mLruProcesses.size();
2545            nextIndex = mLruProcessServiceStart;
2546            inActivity = true;
2547        } else if (hasService) {
2548            // Process has services, put it at the top of the service list.
2549            addIndex = mLruProcessActivityStart;
2550            nextIndex = mLruProcessServiceStart;
2551            inActivity = true;
2552            inService = true;
2553        } else  {
2554            // Process not otherwise of interest, it goes to the top of the non-service area.
2555            addIndex = mLruProcessServiceStart;
2556            if (client != null) {
2557                int clientIndex = mLruProcesses.lastIndexOf(client);
2558                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2559                        + app);
2560                if (clientIndex >= 0 && addIndex > clientIndex) {
2561                    addIndex = clientIndex;
2562                }
2563            }
2564            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2565        }
2566
2567        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2568                + mLruProcessActivityStart + "): " + app);
2569        */
2570
2571        if (lrui >= 0) {
2572            if (lrui < mLruProcessActivityStart) {
2573                mLruProcessActivityStart--;
2574            }
2575            if (lrui < mLruProcessServiceStart) {
2576                mLruProcessServiceStart--;
2577            }
2578            /*
2579            if (addIndex > lrui) {
2580                addIndex--;
2581            }
2582            if (nextIndex > lrui) {
2583                nextIndex--;
2584            }
2585            */
2586            mLruProcesses.remove(lrui);
2587        }
2588
2589        /*
2590        mLruProcesses.add(addIndex, app);
2591        if (inActivity) {
2592            mLruProcessActivityStart++;
2593        }
2594        if (inService) {
2595            mLruProcessActivityStart++;
2596        }
2597        */
2598
2599        int nextIndex;
2600        if (hasActivity) {
2601            final int N = mLruProcesses.size();
2602            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2603                // Process doesn't have activities, but has clients with
2604                // activities...  move it up, but one below the top (the top
2605                // should always have a real activity).
2606                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2607                mLruProcesses.add(N-1, app);
2608                // To keep it from spamming the LRU list (by making a bunch of clients),
2609                // we will push down any other entries owned by the app.
2610                final int uid = app.info.uid;
2611                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2612                    ProcessRecord subProc = mLruProcesses.get(i);
2613                    if (subProc.info.uid == uid) {
2614                        // We want to push this one down the list.  If the process after
2615                        // it is for the same uid, however, don't do so, because we don't
2616                        // want them internally to be re-ordered.
2617                        if (mLruProcesses.get(i-1).info.uid != uid) {
2618                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2619                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2620                            ProcessRecord tmp = mLruProcesses.get(i);
2621                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2622                            mLruProcesses.set(i-1, tmp);
2623                            i--;
2624                        }
2625                    } else {
2626                        // A gap, we can stop here.
2627                        break;
2628                    }
2629                }
2630            } else {
2631                // Process has activities, put it at the very tipsy-top.
2632                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2633                mLruProcesses.add(app);
2634            }
2635            nextIndex = mLruProcessServiceStart;
2636        } else if (hasService) {
2637            // Process has services, put it at the top of the service list.
2638            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2639            mLruProcesses.add(mLruProcessActivityStart, app);
2640            nextIndex = mLruProcessServiceStart;
2641            mLruProcessActivityStart++;
2642        } else  {
2643            // Process not otherwise of interest, it goes to the top of the non-service area.
2644            int index = mLruProcessServiceStart;
2645            if (client != null) {
2646                // If there is a client, don't allow the process to be moved up higher
2647                // in the list than that client.
2648                int clientIndex = mLruProcesses.lastIndexOf(client);
2649                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2650                        + " when updating " + app);
2651                if (clientIndex <= lrui) {
2652                    // Don't allow the client index restriction to push it down farther in the
2653                    // list than it already is.
2654                    clientIndex = lrui;
2655                }
2656                if (clientIndex >= 0 && index > clientIndex) {
2657                    index = clientIndex;
2658                }
2659            }
2660            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2661            mLruProcesses.add(index, app);
2662            nextIndex = index-1;
2663            mLruProcessActivityStart++;
2664            mLruProcessServiceStart++;
2665        }
2666
2667        // If the app is currently using a content provider or service,
2668        // bump those processes as well.
2669        for (int j=app.connections.size()-1; j>=0; j--) {
2670            ConnectionRecord cr = app.connections.valueAt(j);
2671            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2672                    && cr.binding.service.app != null
2673                    && cr.binding.service.app.lruSeq != mLruSeq
2674                    && !cr.binding.service.app.persistent) {
2675                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2676                        "service connection", cr, app);
2677            }
2678        }
2679        for (int j=app.conProviders.size()-1; j>=0; j--) {
2680            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2681            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2682                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2683                        "provider reference", cpr, app);
2684            }
2685        }
2686    }
2687
2688    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2689        if (uid == Process.SYSTEM_UID) {
2690            // The system gets to run in any process.  If there are multiple
2691            // processes with the same uid, just pick the first (this
2692            // should never happen).
2693            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2694            if (procs == null) return null;
2695            final int N = procs.size();
2696            for (int i = 0; i < N; i++) {
2697                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2698            }
2699        }
2700        ProcessRecord proc = mProcessNames.get(processName, uid);
2701        if (false && proc != null && !keepIfLarge
2702                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2703                && proc.lastCachedPss >= 4000) {
2704            // Turn this condition on to cause killing to happen regularly, for testing.
2705            if (proc.baseProcessTracker != null) {
2706                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2707            }
2708            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2709        } else if (proc != null && !keepIfLarge
2710                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2711                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2712            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2713            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2714                if (proc.baseProcessTracker != null) {
2715                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2716                }
2717                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2718            }
2719        }
2720        return proc;
2721    }
2722
2723    void ensurePackageDexOpt(String packageName) {
2724        IPackageManager pm = AppGlobals.getPackageManager();
2725        try {
2726            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2727                mDidDexOpt = true;
2728            }
2729        } catch (RemoteException e) {
2730        }
2731    }
2732
2733    boolean isNextTransitionForward() {
2734        int transit = mWindowManager.getPendingAppTransition();
2735        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2736                || transit == AppTransition.TRANSIT_TASK_OPEN
2737                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2738    }
2739
2740    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2741            String processName, String abiOverride, int uid, Runnable crashHandler) {
2742        synchronized(this) {
2743            ApplicationInfo info = new ApplicationInfo();
2744            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2745            // For isolated processes, the former contains the parent's uid and the latter the
2746            // actual uid of the isolated process.
2747            // In the special case introduced by this method (which is, starting an isolated
2748            // process directly from the SystemServer without an actual parent app process) the
2749            // closest thing to a parent's uid is SYSTEM_UID.
2750            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2751            // the |isolated| logic in the ProcessRecord constructor.
2752            info.uid = Process.SYSTEM_UID;
2753            info.processName = processName;
2754            info.className = entryPoint;
2755            info.packageName = "android";
2756            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2757                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2758                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2759                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2760                    crashHandler);
2761            return proc != null ? proc.pid : 0;
2762        }
2763    }
2764
2765    final ProcessRecord startProcessLocked(String processName,
2766            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2767            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2768            boolean isolated, boolean keepIfLarge) {
2769        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2770                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2771                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2772                null /* crashHandler */);
2773    }
2774
2775    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2776            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2777            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2778            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2779        long startTime = SystemClock.elapsedRealtime();
2780        ProcessRecord app;
2781        if (!isolated) {
2782            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2783            checkTime(startTime, "startProcess: after getProcessRecord");
2784        } else {
2785            // If this is an isolated process, it can't re-use an existing process.
2786            app = null;
2787        }
2788        // We don't have to do anything more if:
2789        // (1) There is an existing application record; and
2790        // (2) The caller doesn't think it is dead, OR there is no thread
2791        //     object attached to it so we know it couldn't have crashed; and
2792        // (3) There is a pid assigned to it, so it is either starting or
2793        //     already running.
2794        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2795                + " app=" + app + " knownToBeDead=" + knownToBeDead
2796                + " thread=" + (app != null ? app.thread : null)
2797                + " pid=" + (app != null ? app.pid : -1));
2798        if (app != null && app.pid > 0) {
2799            if (!knownToBeDead || app.thread == null) {
2800                // We already have the app running, or are waiting for it to
2801                // come up (we have a pid but not yet its thread), so keep it.
2802                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2803                // If this is a new package in the process, add the package to the list
2804                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2805                checkTime(startTime, "startProcess: done, added package to proc");
2806                return app;
2807            }
2808
2809            // An application record is attached to a previous process,
2810            // clean it up now.
2811            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2812            checkTime(startTime, "startProcess: bad proc running, killing");
2813            Process.killProcessGroup(app.info.uid, app.pid);
2814            handleAppDiedLocked(app, true, true);
2815            checkTime(startTime, "startProcess: done killing old proc");
2816        }
2817
2818        String hostingNameStr = hostingName != null
2819                ? hostingName.flattenToShortString() : null;
2820
2821        if (!isolated) {
2822            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2823                // If we are in the background, then check to see if this process
2824                // is bad.  If so, we will just silently fail.
2825                if (mBadProcesses.get(info.processName, info.uid) != null) {
2826                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2827                            + "/" + info.processName);
2828                    return null;
2829                }
2830            } else {
2831                // When the user is explicitly starting a process, then clear its
2832                // crash count so that we won't make it bad until they see at
2833                // least one crash dialog again, and make the process good again
2834                // if it had been bad.
2835                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2836                        + "/" + info.processName);
2837                mProcessCrashTimes.remove(info.processName, info.uid);
2838                if (mBadProcesses.get(info.processName, info.uid) != null) {
2839                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2840                            UserHandle.getUserId(info.uid), info.uid,
2841                            info.processName);
2842                    mBadProcesses.remove(info.processName, info.uid);
2843                    if (app != null) {
2844                        app.bad = false;
2845                    }
2846                }
2847            }
2848        }
2849
2850        if (app == null) {
2851            checkTime(startTime, "startProcess: creating new process record");
2852            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2853            app.crashHandler = crashHandler;
2854            if (app == null) {
2855                Slog.w(TAG, "Failed making new process record for "
2856                        + processName + "/" + info.uid + " isolated=" + isolated);
2857                return null;
2858            }
2859            mProcessNames.put(processName, app.uid, app);
2860            if (isolated) {
2861                mIsolatedProcesses.put(app.uid, app);
2862            }
2863            checkTime(startTime, "startProcess: done creating new process record");
2864        } else {
2865            // If this is a new package in the process, add the package to the list
2866            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2867            checkTime(startTime, "startProcess: added package to existing proc");
2868        }
2869
2870        // If the system is not ready yet, then hold off on starting this
2871        // process until it is.
2872        if (!mProcessesReady
2873                && !isAllowedWhileBooting(info)
2874                && !allowWhileBooting) {
2875            if (!mProcessesOnHold.contains(app)) {
2876                mProcessesOnHold.add(app);
2877            }
2878            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2879            checkTime(startTime, "startProcess: returning with proc on hold");
2880            return app;
2881        }
2882
2883        checkTime(startTime, "startProcess: stepping in to startProcess");
2884        startProcessLocked(
2885                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2886        checkTime(startTime, "startProcess: done starting proc!");
2887        return (app.pid != 0) ? app : null;
2888    }
2889
2890    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2891        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2892    }
2893
2894    private final void startProcessLocked(ProcessRecord app,
2895            String hostingType, String hostingNameStr) {
2896        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2897                null /* entryPoint */, null /* entryPointArgs */);
2898    }
2899
2900    private final void startProcessLocked(ProcessRecord app, String hostingType,
2901            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2902        long startTime = SystemClock.elapsedRealtime();
2903        if (app.pid > 0 && app.pid != MY_PID) {
2904            checkTime(startTime, "startProcess: removing from pids map");
2905            synchronized (mPidsSelfLocked) {
2906                mPidsSelfLocked.remove(app.pid);
2907                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2908            }
2909            checkTime(startTime, "startProcess: done removing from pids map");
2910            app.setPid(0);
2911        }
2912
2913        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2914                "startProcessLocked removing on hold: " + app);
2915        mProcessesOnHold.remove(app);
2916
2917        checkTime(startTime, "startProcess: starting to update cpu stats");
2918        updateCpuStats();
2919        checkTime(startTime, "startProcess: done updating cpu stats");
2920
2921        try {
2922            int uid = app.uid;
2923
2924            int[] gids = null;
2925            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2926            if (!app.isolated) {
2927                int[] permGids = null;
2928                try {
2929                    checkTime(startTime, "startProcess: getting gids from package manager");
2930                    final PackageManager pm = mContext.getPackageManager();
2931                    permGids = pm.getPackageGids(app.info.packageName);
2932
2933                    if (Environment.isExternalStorageEmulated()) {
2934                        checkTime(startTime, "startProcess: checking external storage perm");
2935                        if (pm.checkPermission(
2936                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2937                                app.info.packageName) == PERMISSION_GRANTED) {
2938                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2939                        } else {
2940                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2941                        }
2942                    }
2943                } catch (PackageManager.NameNotFoundException e) {
2944                    Slog.w(TAG, "Unable to retrieve gids", e);
2945                }
2946
2947                /*
2948                 * Add shared application and profile GIDs so applications can share some
2949                 * resources like shared libraries and access user-wide resources
2950                 */
2951                if (permGids == null) {
2952                    gids = new int[2];
2953                } else {
2954                    gids = new int[permGids.length + 2];
2955                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2956                }
2957                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2958                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2959            }
2960            checkTime(startTime, "startProcess: building args");
2961            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2962                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2963                        && mTopComponent != null
2964                        && app.processName.equals(mTopComponent.getPackageName())) {
2965                    uid = 0;
2966                }
2967                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2968                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2969                    uid = 0;
2970                }
2971            }
2972            int debugFlags = 0;
2973            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2974                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2975                // Also turn on CheckJNI for debuggable apps. It's quite
2976                // awkward to turn on otherwise.
2977                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2978            }
2979            // Run the app in safe mode if its manifest requests so or the
2980            // system is booted in safe mode.
2981            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2982                mSafeMode == true) {
2983                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2984            }
2985            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2986                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2987            }
2988            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2989                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2990            }
2991            if ("1".equals(SystemProperties.get("debug.assert"))) {
2992                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2993            }
2994
2995            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2996            if (requiredAbi == null) {
2997                requiredAbi = Build.SUPPORTED_ABIS[0];
2998            }
2999
3000            String instructionSet = null;
3001            if (app.info.primaryCpuAbi != null) {
3002                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3003            }
3004
3005            // Start the process.  It will either succeed and return a result containing
3006            // the PID of the new process, or else throw a RuntimeException.
3007            boolean isActivityProcess = (entryPoint == null);
3008            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3009            checkTime(startTime, "startProcess: asking zygote to start proc");
3010            Process.ProcessStartResult startResult = Process.start(entryPoint,
3011                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3012                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3013                    app.info.dataDir, entryPointArgs);
3014            checkTime(startTime, "startProcess: returned from zygote!");
3015
3016            if (app.isolated) {
3017                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3018            }
3019            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3020            checkTime(startTime, "startProcess: done updating battery stats");
3021
3022            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3023                    UserHandle.getUserId(uid), startResult.pid, uid,
3024                    app.processName, hostingType,
3025                    hostingNameStr != null ? hostingNameStr : "");
3026
3027            if (app.persistent) {
3028                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3029            }
3030
3031            checkTime(startTime, "startProcess: building log message");
3032            StringBuilder buf = mStringBuilder;
3033            buf.setLength(0);
3034            buf.append("Start proc ");
3035            buf.append(app.processName);
3036            if (!isActivityProcess) {
3037                buf.append(" [");
3038                buf.append(entryPoint);
3039                buf.append("]");
3040            }
3041            buf.append(" for ");
3042            buf.append(hostingType);
3043            if (hostingNameStr != null) {
3044                buf.append(" ");
3045                buf.append(hostingNameStr);
3046            }
3047            buf.append(": pid=");
3048            buf.append(startResult.pid);
3049            buf.append(" uid=");
3050            buf.append(uid);
3051            buf.append(" gids={");
3052            if (gids != null) {
3053                for (int gi=0; gi<gids.length; gi++) {
3054                    if (gi != 0) buf.append(", ");
3055                    buf.append(gids[gi]);
3056
3057                }
3058            }
3059            buf.append("}");
3060            if (requiredAbi != null) {
3061                buf.append(" abi=");
3062                buf.append(requiredAbi);
3063            }
3064            Slog.i(TAG, buf.toString());
3065            app.setPid(startResult.pid);
3066            app.usingWrapper = startResult.usingWrapper;
3067            app.removed = false;
3068            app.killed = false;
3069            app.killedByAm = false;
3070            checkTime(startTime, "startProcess: starting to update pids map");
3071            synchronized (mPidsSelfLocked) {
3072                this.mPidsSelfLocked.put(startResult.pid, app);
3073                if (isActivityProcess) {
3074                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3075                    msg.obj = app;
3076                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3077                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3078                }
3079            }
3080            checkTime(startTime, "startProcess: done updating pids map");
3081        } catch (RuntimeException e) {
3082            // XXX do better error recovery.
3083            app.setPid(0);
3084            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3085            if (app.isolated) {
3086                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3087            }
3088            Slog.e(TAG, "Failure starting process " + app.processName, e);
3089        }
3090    }
3091
3092    void updateUsageStats(ActivityRecord component, boolean resumed) {
3093        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3094        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3095        if (resumed) {
3096            if (mUsageStatsService != null) {
3097                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3098                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3099            }
3100            synchronized (stats) {
3101                stats.noteActivityResumedLocked(component.app.uid);
3102            }
3103        } else {
3104            if (mUsageStatsService != null) {
3105                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3106                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3107            }
3108            synchronized (stats) {
3109                stats.noteActivityPausedLocked(component.app.uid);
3110            }
3111        }
3112    }
3113
3114    Intent getHomeIntent() {
3115        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3116        intent.setComponent(mTopComponent);
3117        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3118            intent.addCategory(Intent.CATEGORY_HOME);
3119        }
3120        return intent;
3121    }
3122
3123    boolean startHomeActivityLocked(int userId) {
3124        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3125                && mTopAction == null) {
3126            // We are running in factory test mode, but unable to find
3127            // the factory test app, so just sit around displaying the
3128            // error message and don't try to start anything.
3129            return false;
3130        }
3131        Intent intent = getHomeIntent();
3132        ActivityInfo aInfo =
3133            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3134        if (aInfo != null) {
3135            intent.setComponent(new ComponentName(
3136                    aInfo.applicationInfo.packageName, aInfo.name));
3137            // Don't do this if the home app is currently being
3138            // instrumented.
3139            aInfo = new ActivityInfo(aInfo);
3140            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3141            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3142                    aInfo.applicationInfo.uid, true);
3143            if (app == null || app.instrumentationClass == null) {
3144                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3145                mStackSupervisor.startHomeActivity(intent, aInfo);
3146            }
3147        }
3148
3149        return true;
3150    }
3151
3152    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3153        ActivityInfo ai = null;
3154        ComponentName comp = intent.getComponent();
3155        try {
3156            if (comp != null) {
3157                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3158            } else {
3159                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3160                        intent,
3161                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3162                            flags, userId);
3163
3164                if (info != null) {
3165                    ai = info.activityInfo;
3166                }
3167            }
3168        } catch (RemoteException e) {
3169            // ignore
3170        }
3171
3172        return ai;
3173    }
3174
3175    /**
3176     * Starts the "new version setup screen" if appropriate.
3177     */
3178    void startSetupActivityLocked() {
3179        // Only do this once per boot.
3180        if (mCheckedForSetup) {
3181            return;
3182        }
3183
3184        // We will show this screen if the current one is a different
3185        // version than the last one shown, and we are not running in
3186        // low-level factory test mode.
3187        final ContentResolver resolver = mContext.getContentResolver();
3188        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3189                Settings.Global.getInt(resolver,
3190                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3191            mCheckedForSetup = true;
3192
3193            // See if we should be showing the platform update setup UI.
3194            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3195            List<ResolveInfo> ris = mContext.getPackageManager()
3196                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3197
3198            // We don't allow third party apps to replace this.
3199            ResolveInfo ri = null;
3200            for (int i=0; ris != null && i<ris.size(); i++) {
3201                if ((ris.get(i).activityInfo.applicationInfo.flags
3202                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3203                    ri = ris.get(i);
3204                    break;
3205                }
3206            }
3207
3208            if (ri != null) {
3209                String vers = ri.activityInfo.metaData != null
3210                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3211                        : null;
3212                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3213                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3214                            Intent.METADATA_SETUP_VERSION);
3215                }
3216                String lastVers = Settings.Secure.getString(
3217                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3218                if (vers != null && !vers.equals(lastVers)) {
3219                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3220                    intent.setComponent(new ComponentName(
3221                            ri.activityInfo.packageName, ri.activityInfo.name));
3222                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3223                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3224                            null);
3225                }
3226            }
3227        }
3228    }
3229
3230    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3231        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3232    }
3233
3234    void enforceNotIsolatedCaller(String caller) {
3235        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3236            throw new SecurityException("Isolated process not allowed to call " + caller);
3237        }
3238    }
3239
3240    void enforceShellRestriction(String restriction, int userHandle) {
3241        if (Binder.getCallingUid() == Process.SHELL_UID) {
3242            if (userHandle < 0
3243                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3244                throw new SecurityException("Shell does not have permission to access user "
3245                        + userHandle);
3246            }
3247        }
3248    }
3249
3250    @Override
3251    public int getFrontActivityScreenCompatMode() {
3252        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3253        synchronized (this) {
3254            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3255        }
3256    }
3257
3258    @Override
3259    public void setFrontActivityScreenCompatMode(int mode) {
3260        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3261                "setFrontActivityScreenCompatMode");
3262        synchronized (this) {
3263            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3264        }
3265    }
3266
3267    @Override
3268    public int getPackageScreenCompatMode(String packageName) {
3269        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3270        synchronized (this) {
3271            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3272        }
3273    }
3274
3275    @Override
3276    public void setPackageScreenCompatMode(String packageName, int mode) {
3277        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3278                "setPackageScreenCompatMode");
3279        synchronized (this) {
3280            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3281        }
3282    }
3283
3284    @Override
3285    public boolean getPackageAskScreenCompat(String packageName) {
3286        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3287        synchronized (this) {
3288            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3289        }
3290    }
3291
3292    @Override
3293    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3294        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3295                "setPackageAskScreenCompat");
3296        synchronized (this) {
3297            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3298        }
3299    }
3300
3301    private void dispatchProcessesChanged() {
3302        int N;
3303        synchronized (this) {
3304            N = mPendingProcessChanges.size();
3305            if (mActiveProcessChanges.length < N) {
3306                mActiveProcessChanges = new ProcessChangeItem[N];
3307            }
3308            mPendingProcessChanges.toArray(mActiveProcessChanges);
3309            mAvailProcessChanges.addAll(mPendingProcessChanges);
3310            mPendingProcessChanges.clear();
3311            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3312        }
3313
3314        int i = mProcessObservers.beginBroadcast();
3315        while (i > 0) {
3316            i--;
3317            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3318            if (observer != null) {
3319                try {
3320                    for (int j=0; j<N; j++) {
3321                        ProcessChangeItem item = mActiveProcessChanges[j];
3322                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3323                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3324                                    + item.pid + " uid=" + item.uid + ": "
3325                                    + item.foregroundActivities);
3326                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3327                                    item.foregroundActivities);
3328                        }
3329                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3330                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3331                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3332                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3333                        }
3334                    }
3335                } catch (RemoteException e) {
3336                }
3337            }
3338        }
3339        mProcessObservers.finishBroadcast();
3340    }
3341
3342    private void dispatchProcessDied(int pid, int uid) {
3343        int i = mProcessObservers.beginBroadcast();
3344        while (i > 0) {
3345            i--;
3346            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3347            if (observer != null) {
3348                try {
3349                    observer.onProcessDied(pid, uid);
3350                } catch (RemoteException e) {
3351                }
3352            }
3353        }
3354        mProcessObservers.finishBroadcast();
3355    }
3356
3357    @Override
3358    public final int startActivity(IApplicationThread caller, String callingPackage,
3359            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3360            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3361        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3362            resultWho, requestCode, startFlags, profilerInfo, options,
3363            UserHandle.getCallingUserId());
3364    }
3365
3366    @Override
3367    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3368            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3369            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3370        enforceNotIsolatedCaller("startActivity");
3371        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3372                false, ALLOW_FULL_ONLY, "startActivity", null);
3373        // TODO: Switch to user app stacks here.
3374        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3375                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3376                profilerInfo, null, null, options, userId, null, null);
3377    }
3378
3379    @Override
3380    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3381            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3382            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3383
3384        // This is very dangerous -- it allows you to perform a start activity (including
3385        // permission grants) as any app that may launch one of your own activities.  So
3386        // we will only allow this to be done from activities that are part of the core framework,
3387        // and then only when they are running as the system.
3388        final ActivityRecord sourceRecord;
3389        final int targetUid;
3390        final String targetPackage;
3391        synchronized (this) {
3392            if (resultTo == null) {
3393                throw new SecurityException("Must be called from an activity");
3394            }
3395            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3396            if (sourceRecord == null) {
3397                throw new SecurityException("Called with bad activity token: " + resultTo);
3398            }
3399            if (!sourceRecord.info.packageName.equals("android")) {
3400                throw new SecurityException(
3401                        "Must be called from an activity that is declared in the android package");
3402            }
3403            if (sourceRecord.app == null) {
3404                throw new SecurityException("Called without a process attached to activity");
3405            }
3406            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3407                // This is still okay, as long as this activity is running under the
3408                // uid of the original calling activity.
3409                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3410                    throw new SecurityException(
3411                            "Calling activity in uid " + sourceRecord.app.uid
3412                                    + " must be system uid or original calling uid "
3413                                    + sourceRecord.launchedFromUid);
3414                }
3415            }
3416            targetUid = sourceRecord.launchedFromUid;
3417            targetPackage = sourceRecord.launchedFromPackage;
3418        }
3419
3420        if (userId == UserHandle.USER_NULL) {
3421            userId = UserHandle.getUserId(sourceRecord.app.uid);
3422        }
3423
3424        // TODO: Switch to user app stacks here.
3425        try {
3426            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3427                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3428                    null, null, options, userId, null, null);
3429            return ret;
3430        } catch (SecurityException e) {
3431            // XXX need to figure out how to propagate to original app.
3432            // A SecurityException here is generally actually a fault of the original
3433            // calling activity (such as a fairly granting permissions), so propagate it
3434            // back to them.
3435            /*
3436            StringBuilder msg = new StringBuilder();
3437            msg.append("While launching");
3438            msg.append(intent.toString());
3439            msg.append(": ");
3440            msg.append(e.getMessage());
3441            */
3442            throw e;
3443        }
3444    }
3445
3446    @Override
3447    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3448            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3449            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3450        enforceNotIsolatedCaller("startActivityAndWait");
3451        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3452                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3453        WaitResult res = new WaitResult();
3454        // TODO: Switch to user app stacks here.
3455        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3456                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3457                options, userId, null, null);
3458        return res;
3459    }
3460
3461    @Override
3462    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3463            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3464            int startFlags, Configuration config, Bundle options, int userId) {
3465        enforceNotIsolatedCaller("startActivityWithConfig");
3466        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3467                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3468        // TODO: Switch to user app stacks here.
3469        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3470                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3471                null, null, config, options, userId, null, null);
3472        return ret;
3473    }
3474
3475    @Override
3476    public int startActivityIntentSender(IApplicationThread caller,
3477            IntentSender intent, Intent fillInIntent, String resolvedType,
3478            IBinder resultTo, String resultWho, int requestCode,
3479            int flagsMask, int flagsValues, Bundle options) {
3480        enforceNotIsolatedCaller("startActivityIntentSender");
3481        // Refuse possible leaked file descriptors
3482        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3483            throw new IllegalArgumentException("File descriptors passed in Intent");
3484        }
3485
3486        IIntentSender sender = intent.getTarget();
3487        if (!(sender instanceof PendingIntentRecord)) {
3488            throw new IllegalArgumentException("Bad PendingIntent object");
3489        }
3490
3491        PendingIntentRecord pir = (PendingIntentRecord)sender;
3492
3493        synchronized (this) {
3494            // If this is coming from the currently resumed activity, it is
3495            // effectively saying that app switches are allowed at this point.
3496            final ActivityStack stack = getFocusedStack();
3497            if (stack.mResumedActivity != null &&
3498                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3499                mAppSwitchesAllowedTime = 0;
3500            }
3501        }
3502        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3503                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3504        return ret;
3505    }
3506
3507    @Override
3508    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3509            Intent intent, String resolvedType, IVoiceInteractionSession session,
3510            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3511            Bundle options, int userId) {
3512        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3513                != PackageManager.PERMISSION_GRANTED) {
3514            String msg = "Permission Denial: startVoiceActivity() from pid="
3515                    + Binder.getCallingPid()
3516                    + ", uid=" + Binder.getCallingUid()
3517                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3518            Slog.w(TAG, msg);
3519            throw new SecurityException(msg);
3520        }
3521        if (session == null || interactor == null) {
3522            throw new NullPointerException("null session or interactor");
3523        }
3524        userId = handleIncomingUser(callingPid, callingUid, userId,
3525                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3526        // TODO: Switch to user app stacks here.
3527        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3528                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3529                null, options, userId, null, null);
3530    }
3531
3532    @Override
3533    public boolean startNextMatchingActivity(IBinder callingActivity,
3534            Intent intent, Bundle options) {
3535        // Refuse possible leaked file descriptors
3536        if (intent != null && intent.hasFileDescriptors() == true) {
3537            throw new IllegalArgumentException("File descriptors passed in Intent");
3538        }
3539
3540        synchronized (this) {
3541            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3542            if (r == null) {
3543                ActivityOptions.abort(options);
3544                return false;
3545            }
3546            if (r.app == null || r.app.thread == null) {
3547                // The caller is not running...  d'oh!
3548                ActivityOptions.abort(options);
3549                return false;
3550            }
3551            intent = new Intent(intent);
3552            // The caller is not allowed to change the data.
3553            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3554            // And we are resetting to find the next component...
3555            intent.setComponent(null);
3556
3557            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3558
3559            ActivityInfo aInfo = null;
3560            try {
3561                List<ResolveInfo> resolves =
3562                    AppGlobals.getPackageManager().queryIntentActivities(
3563                            intent, r.resolvedType,
3564                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3565                            UserHandle.getCallingUserId());
3566
3567                // Look for the original activity in the list...
3568                final int N = resolves != null ? resolves.size() : 0;
3569                for (int i=0; i<N; i++) {
3570                    ResolveInfo rInfo = resolves.get(i);
3571                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3572                            && rInfo.activityInfo.name.equals(r.info.name)) {
3573                        // We found the current one...  the next matching is
3574                        // after it.
3575                        i++;
3576                        if (i<N) {
3577                            aInfo = resolves.get(i).activityInfo;
3578                        }
3579                        if (debug) {
3580                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3581                                    + "/" + r.info.name);
3582                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3583                                    + "/" + aInfo.name);
3584                        }
3585                        break;
3586                    }
3587                }
3588            } catch (RemoteException e) {
3589            }
3590
3591            if (aInfo == null) {
3592                // Nobody who is next!
3593                ActivityOptions.abort(options);
3594                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3595                return false;
3596            }
3597
3598            intent.setComponent(new ComponentName(
3599                    aInfo.applicationInfo.packageName, aInfo.name));
3600            intent.setFlags(intent.getFlags()&~(
3601                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3602                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3603                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3604                    Intent.FLAG_ACTIVITY_NEW_TASK));
3605
3606            // Okay now we need to start the new activity, replacing the
3607            // currently running activity.  This is a little tricky because
3608            // we want to start the new one as if the current one is finished,
3609            // but not finish the current one first so that there is no flicker.
3610            // And thus...
3611            final boolean wasFinishing = r.finishing;
3612            r.finishing = true;
3613
3614            // Propagate reply information over to the new activity.
3615            final ActivityRecord resultTo = r.resultTo;
3616            final String resultWho = r.resultWho;
3617            final int requestCode = r.requestCode;
3618            r.resultTo = null;
3619            if (resultTo != null) {
3620                resultTo.removeResultsLocked(r, resultWho, requestCode);
3621            }
3622
3623            final long origId = Binder.clearCallingIdentity();
3624            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3625                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3626                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3627                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3628            Binder.restoreCallingIdentity(origId);
3629
3630            r.finishing = wasFinishing;
3631            if (res != ActivityManager.START_SUCCESS) {
3632                return false;
3633            }
3634            return true;
3635        }
3636    }
3637
3638    @Override
3639    public final int startActivityFromRecents(int taskId, Bundle options) {
3640        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3641            String msg = "Permission Denial: startActivityFromRecents called without " +
3642                    START_TASKS_FROM_RECENTS;
3643            Slog.w(TAG, msg);
3644            throw new SecurityException(msg);
3645        }
3646        return startActivityFromRecentsInner(taskId, options);
3647    }
3648
3649    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3650        final TaskRecord task;
3651        final int callingUid;
3652        final String callingPackage;
3653        final Intent intent;
3654        final int userId;
3655        synchronized (this) {
3656            task = recentTaskForIdLocked(taskId);
3657            if (task == null) {
3658                throw new IllegalArgumentException("Task " + taskId + " not found.");
3659            }
3660            callingUid = task.mCallingUid;
3661            callingPackage = task.mCallingPackage;
3662            intent = task.intent;
3663            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3664            userId = task.userId;
3665        }
3666        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3667                options, userId, null, task);
3668    }
3669
3670    final int startActivityInPackage(int uid, String callingPackage,
3671            Intent intent, String resolvedType, IBinder resultTo,
3672            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3673            IActivityContainer container, TaskRecord inTask) {
3674
3675        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3676                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3677
3678        // TODO: Switch to user app stacks here.
3679        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3680                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3681                null, null, null, options, userId, container, inTask);
3682        return ret;
3683    }
3684
3685    @Override
3686    public final int startActivities(IApplicationThread caller, String callingPackage,
3687            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3688            int userId) {
3689        enforceNotIsolatedCaller("startActivities");
3690        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3691                false, ALLOW_FULL_ONLY, "startActivity", null);
3692        // TODO: Switch to user app stacks here.
3693        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3694                resolvedTypes, resultTo, options, userId);
3695        return ret;
3696    }
3697
3698    final int startActivitiesInPackage(int uid, String callingPackage,
3699            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3700            Bundle options, int userId) {
3701
3702        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3703                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3704        // TODO: Switch to user app stacks here.
3705        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3706                resultTo, options, userId);
3707        return ret;
3708    }
3709
3710    //explicitly remove thd old information in mRecentTasks when removing existing user.
3711    private void removeRecentTasksForUserLocked(int userId) {
3712        if(userId <= 0) {
3713            Slog.i(TAG, "Can't remove recent task on user " + userId);
3714            return;
3715        }
3716
3717        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3718            TaskRecord tr = mRecentTasks.get(i);
3719            if (tr.userId == userId) {
3720                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3721                        + " when finishing user" + userId);
3722                mRecentTasks.remove(i);
3723                tr.removedFromRecents(mTaskPersister);
3724            }
3725        }
3726
3727        // Remove tasks from persistent storage.
3728        mTaskPersister.wakeup(null, true);
3729    }
3730
3731    // Sort by taskId
3732    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3733        @Override
3734        public int compare(TaskRecord lhs, TaskRecord rhs) {
3735            return rhs.taskId - lhs.taskId;
3736        }
3737    };
3738
3739    // Extract the affiliates of the chain containing mRecentTasks[start].
3740    private int processNextAffiliateChain(int start) {
3741        final TaskRecord startTask = mRecentTasks.get(start);
3742        final int affiliateId = startTask.mAffiliatedTaskId;
3743
3744        // Quick identification of isolated tasks. I.e. those not launched behind.
3745        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3746                startTask.mNextAffiliate == null) {
3747            // There is still a slim chance that there are other tasks that point to this task
3748            // and that the chain is so messed up that this task no longer points to them but
3749            // the gain of this optimization outweighs the risk.
3750            startTask.inRecents = true;
3751            return start + 1;
3752        }
3753
3754        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3755        mTmpRecents.clear();
3756        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3757            final TaskRecord task = mRecentTasks.get(i);
3758            if (task.mAffiliatedTaskId == affiliateId) {
3759                mRecentTasks.remove(i);
3760                mTmpRecents.add(task);
3761            }
3762        }
3763
3764        // Sort them all by taskId. That is the order they were create in and that order will
3765        // always be correct.
3766        Collections.sort(mTmpRecents, mTaskRecordComparator);
3767
3768        // Go through and fix up the linked list.
3769        // The first one is the end of the chain and has no next.
3770        final TaskRecord first = mTmpRecents.get(0);
3771        first.inRecents = true;
3772        if (first.mNextAffiliate != null) {
3773            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3774            first.setNextAffiliate(null);
3775            mTaskPersister.wakeup(first, false);
3776        }
3777        // Everything in the middle is doubly linked from next to prev.
3778        final int tmpSize = mTmpRecents.size();
3779        for (int i = 0; i < tmpSize - 1; ++i) {
3780            final TaskRecord next = mTmpRecents.get(i);
3781            final TaskRecord prev = mTmpRecents.get(i + 1);
3782            if (next.mPrevAffiliate != prev) {
3783                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3784                        " setting prev=" + prev);
3785                next.setPrevAffiliate(prev);
3786                mTaskPersister.wakeup(next, false);
3787            }
3788            if (prev.mNextAffiliate != next) {
3789                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3790                        " setting next=" + next);
3791                prev.setNextAffiliate(next);
3792                mTaskPersister.wakeup(prev, false);
3793            }
3794            prev.inRecents = true;
3795        }
3796        // The last one is the beginning of the list and has no prev.
3797        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3798        if (last.mPrevAffiliate != null) {
3799            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3800            last.setPrevAffiliate(null);
3801            mTaskPersister.wakeup(last, false);
3802        }
3803
3804        // Insert the group back into mRecentTasks at start.
3805        mRecentTasks.addAll(start, mTmpRecents);
3806
3807        // Let the caller know where we left off.
3808        return start + tmpSize;
3809    }
3810
3811    /**
3812     * Update the recent tasks lists: make sure tasks should still be here (their
3813     * applications / activities still exist), update their availability, fixup ordering
3814     * of affiliations.
3815     */
3816    void cleanupRecentTasksLocked(int userId) {
3817        if (mRecentTasks == null) {
3818            // Happens when called from the packagemanager broadcast before boot.
3819            return;
3820        }
3821
3822        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3823        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3824        final IPackageManager pm = AppGlobals.getPackageManager();
3825        final ActivityInfo dummyAct = new ActivityInfo();
3826        final ApplicationInfo dummyApp = new ApplicationInfo();
3827
3828        int N = mRecentTasks.size();
3829
3830        int[] users = userId == UserHandle.USER_ALL
3831                ? getUsersLocked() : new int[] { userId };
3832        for (int user : users) {
3833            for (int i = 0; i < N; i++) {
3834                TaskRecord task = mRecentTasks.get(i);
3835                if (task.userId != user) {
3836                    // Only look at tasks for the user ID of interest.
3837                    continue;
3838                }
3839                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3840                    // This situation is broken, and we should just get rid of it now.
3841                    mRecentTasks.remove(i);
3842                    task.removedFromRecents(mTaskPersister);
3843                    i--;
3844                    N--;
3845                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3846                    continue;
3847                }
3848                // Check whether this activity is currently available.
3849                if (task.realActivity != null) {
3850                    ActivityInfo ai = availActCache.get(task.realActivity);
3851                    if (ai == null) {
3852                        try {
3853                            ai = pm.getActivityInfo(task.realActivity,
3854                                    PackageManager.GET_UNINSTALLED_PACKAGES
3855                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3856                        } catch (RemoteException e) {
3857                            // Will never happen.
3858                            continue;
3859                        }
3860                        if (ai == null) {
3861                            ai = dummyAct;
3862                        }
3863                        availActCache.put(task.realActivity, ai);
3864                    }
3865                    if (ai == dummyAct) {
3866                        // This could be either because the activity no longer exists, or the
3867                        // app is temporarily gone.  For the former we want to remove the recents
3868                        // entry; for the latter we want to mark it as unavailable.
3869                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3870                        if (app == null) {
3871                            try {
3872                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3873                                        PackageManager.GET_UNINSTALLED_PACKAGES
3874                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3875                            } catch (RemoteException e) {
3876                                // Will never happen.
3877                                continue;
3878                            }
3879                            if (app == null) {
3880                                app = dummyApp;
3881                            }
3882                            availAppCache.put(task.realActivity.getPackageName(), app);
3883                        }
3884                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3885                            // Doesn't exist any more!  Good-bye.
3886                            mRecentTasks.remove(i);
3887                            task.removedFromRecents(mTaskPersister);
3888                            i--;
3889                            N--;
3890                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3891                            continue;
3892                        } else {
3893                            // Otherwise just not available for now.
3894                            if (task.isAvailable) {
3895                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3896                                        + task);
3897                            }
3898                            task.isAvailable = false;
3899                        }
3900                    } else {
3901                        if (!ai.enabled || !ai.applicationInfo.enabled
3902                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3903                            if (task.isAvailable) {
3904                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3905                                        + task + " (enabled=" + ai.enabled + "/"
3906                                        + ai.applicationInfo.enabled +  " flags="
3907                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3908                            }
3909                            task.isAvailable = false;
3910                        } else {
3911                            if (!task.isAvailable) {
3912                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3913                                        + task);
3914                            }
3915                            task.isAvailable = true;
3916                        }
3917                    }
3918                }
3919            }
3920        }
3921
3922        // Verify the affiliate chain for each task.
3923        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
3924        }
3925
3926        mTmpRecents.clear();
3927        // mRecentTasks is now in sorted, affiliated order.
3928    }
3929
3930    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3931        int N = mRecentTasks.size();
3932        TaskRecord top = task;
3933        int topIndex = taskIndex;
3934        while (top.mNextAffiliate != null && topIndex > 0) {
3935            top = top.mNextAffiliate;
3936            topIndex--;
3937        }
3938        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3939                + topIndex + " from intial " + taskIndex);
3940        // Find the end of the chain, doing a sanity check along the way.
3941        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3942        int endIndex = topIndex;
3943        TaskRecord prev = top;
3944        while (endIndex < N) {
3945            TaskRecord cur = mRecentTasks.get(endIndex);
3946            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3947                    + endIndex + " " + cur);
3948            if (cur == top) {
3949                // Verify start of the chain.
3950                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3951                    Slog.wtf(TAG, "Bad chain @" + endIndex
3952                            + ": first task has next affiliate: " + prev);
3953                    sane = false;
3954                    break;
3955                }
3956            } else {
3957                // Verify middle of the chain's next points back to the one before.
3958                if (cur.mNextAffiliate != prev
3959                        || cur.mNextAffiliateTaskId != prev.taskId) {
3960                    Slog.wtf(TAG, "Bad chain @" + endIndex
3961                            + ": middle task " + cur + " @" + endIndex
3962                            + " has bad next affiliate "
3963                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3964                            + ", expected " + prev);
3965                    sane = false;
3966                    break;
3967                }
3968            }
3969            if (cur.mPrevAffiliateTaskId == -1) {
3970                // Chain ends here.
3971                if (cur.mPrevAffiliate != null) {
3972                    Slog.wtf(TAG, "Bad chain @" + endIndex
3973                            + ": last task " + cur + " has previous affiliate "
3974                            + cur.mPrevAffiliate);
3975                    sane = false;
3976                }
3977                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3978                break;
3979            } else {
3980                // Verify middle of the chain's prev points to a valid item.
3981                if (cur.mPrevAffiliate == null) {
3982                    Slog.wtf(TAG, "Bad chain @" + endIndex
3983                            + ": task " + cur + " has previous affiliate "
3984                            + cur.mPrevAffiliate + " but should be id "
3985                            + cur.mPrevAffiliate);
3986                    sane = false;
3987                    break;
3988                }
3989            }
3990            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3991                Slog.wtf(TAG, "Bad chain @" + endIndex
3992                        + ": task " + cur + " has affiliated id "
3993                        + cur.mAffiliatedTaskId + " but should be "
3994                        + task.mAffiliatedTaskId);
3995                sane = false;
3996                break;
3997            }
3998            prev = cur;
3999            endIndex++;
4000            if (endIndex >= N) {
4001                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4002                        + ": last task " + prev);
4003                sane = false;
4004                break;
4005            }
4006        }
4007        if (sane) {
4008            if (endIndex < taskIndex) {
4009                Slog.wtf(TAG, "Bad chain @" + endIndex
4010                        + ": did not extend to task " + task + " @" + taskIndex);
4011                sane = false;
4012            }
4013        }
4014        if (sane) {
4015            // All looks good, we can just move all of the affiliated tasks
4016            // to the top.
4017            for (int i=topIndex; i<=endIndex; i++) {
4018                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4019                        + " from " + i + " to " + (i-topIndex));
4020                TaskRecord cur = mRecentTasks.remove(i);
4021                mRecentTasks.add(i-topIndex, cur);
4022            }
4023            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4024                    + " to " + endIndex);
4025            return true;
4026        }
4027
4028        // Whoops, couldn't do it.
4029        return false;
4030    }
4031
4032    final void addRecentTaskLocked(TaskRecord task) {
4033        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4034                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4035
4036        int N = mRecentTasks.size();
4037        // Quick case: check if the top-most recent task is the same.
4038        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4039            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4040            return;
4041        }
4042        // Another quick case: check if this is part of a set of affiliated
4043        // tasks that are at the top.
4044        if (isAffiliated && N > 0 && task.inRecents
4045                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4046            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4047                    + " at top when adding " + task);
4048            return;
4049        }
4050        // Another quick case: never add voice sessions.
4051        if (task.voiceSession != null) {
4052            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4053            return;
4054        }
4055
4056        boolean needAffiliationFix = false;
4057
4058        // Slightly less quick case: the task is already in recents, so all we need
4059        // to do is move it.
4060        if (task.inRecents) {
4061            int taskIndex = mRecentTasks.indexOf(task);
4062            if (taskIndex >= 0) {
4063                if (!isAffiliated) {
4064                    // Simple case: this is not an affiliated task, so we just move it to the front.
4065                    mRecentTasks.remove(taskIndex);
4066                    mRecentTasks.add(0, task);
4067                    notifyTaskPersisterLocked(task, false);
4068                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4069                            + " from " + taskIndex);
4070                    return;
4071                } else {
4072                    // More complicated: need to keep all affiliated tasks together.
4073                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4074                        // All went well.
4075                        return;
4076                    }
4077
4078                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4079                    // everything and then go through our general path of adding a new task.
4080                    needAffiliationFix = true;
4081                }
4082            } else {
4083                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4084                needAffiliationFix = true;
4085            }
4086        }
4087
4088        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4089        trimRecentsForTask(task, true);
4090
4091        N = mRecentTasks.size();
4092        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4093            final TaskRecord tr = mRecentTasks.remove(N - 1);
4094            tr.removedFromRecents(mTaskPersister);
4095            N--;
4096        }
4097        task.inRecents = true;
4098        if (!isAffiliated || needAffiliationFix) {
4099            // If this is a simple non-affiliated task, or we had some failure trying to
4100            // handle it as part of an affilated task, then just place it at the top.
4101            mRecentTasks.add(0, task);
4102        } else if (isAffiliated) {
4103            // If this is a new affiliated task, then move all of the affiliated tasks
4104            // to the front and insert this new one.
4105            TaskRecord other = task.mNextAffiliate;
4106            if (other == null) {
4107                other = task.mPrevAffiliate;
4108            }
4109            if (other != null) {
4110                int otherIndex = mRecentTasks.indexOf(other);
4111                if (otherIndex >= 0) {
4112                    // Insert new task at appropriate location.
4113                    int taskIndex;
4114                    if (other == task.mNextAffiliate) {
4115                        // We found the index of our next affiliation, which is who is
4116                        // before us in the list, so add after that point.
4117                        taskIndex = otherIndex+1;
4118                    } else {
4119                        // We found the index of our previous affiliation, which is who is
4120                        // after us in the list, so add at their position.
4121                        taskIndex = otherIndex;
4122                    }
4123                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4124                            + taskIndex + ": " + task);
4125                    mRecentTasks.add(taskIndex, task);
4126
4127                    // Now move everything to the front.
4128                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4129                        // All went well.
4130                        return;
4131                    }
4132
4133                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4134                    // everything and then go through our general path of adding a new task.
4135                    needAffiliationFix = true;
4136                } else {
4137                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4138                            + other);
4139                    needAffiliationFix = true;
4140                }
4141            } else {
4142                if (DEBUG_RECENTS) Slog.d(TAG,
4143                        "addRecent: adding affiliated task without next/prev:" + task);
4144                needAffiliationFix = true;
4145            }
4146        }
4147        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4148
4149        if (needAffiliationFix) {
4150            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4151            cleanupRecentTasksLocked(task.userId);
4152        }
4153    }
4154
4155    /**
4156     * If needed, remove oldest existing entries in recents that are for the same kind
4157     * of task as the given one.
4158     */
4159    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4160        int N = mRecentTasks.size();
4161        final Intent intent = task.intent;
4162        final boolean document = intent != null && intent.isDocument();
4163
4164        int maxRecents = task.maxRecents - 1;
4165        for (int i=0; i<N; i++) {
4166            final TaskRecord tr = mRecentTasks.get(i);
4167            if (task != tr) {
4168                if (task.userId != tr.userId) {
4169                    continue;
4170                }
4171                if (i > MAX_RECENT_BITMAPS) {
4172                    tr.freeLastThumbnail();
4173                }
4174                final Intent trIntent = tr.intent;
4175                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4176                    (intent == null || !intent.filterEquals(trIntent))) {
4177                    continue;
4178                }
4179                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4180                if (document && trIsDocument) {
4181                    // These are the same document activity (not necessarily the same doc).
4182                    if (maxRecents > 0) {
4183                        --maxRecents;
4184                        continue;
4185                    }
4186                    // Hit the maximum number of documents for this task. Fall through
4187                    // and remove this document from recents.
4188                } else if (document || trIsDocument) {
4189                    // Only one of these is a document. Not the droid we're looking for.
4190                    continue;
4191                }
4192            }
4193
4194            if (!doTrim) {
4195                // If the caller is not actually asking for a trim, just tell them we reached
4196                // a point where the trim would happen.
4197                return i;
4198            }
4199
4200            // Either task and tr are the same or, their affinities match or their intents match
4201            // and neither of them is a document, or they are documents using the same activity
4202            // and their maxRecents has been reached.
4203            tr.disposeThumbnail();
4204            mRecentTasks.remove(i);
4205            if (task != tr) {
4206                tr.removedFromRecents(mTaskPersister);
4207            }
4208            i--;
4209            N--;
4210            if (task.intent == null) {
4211                // If the new recent task we are adding is not fully
4212                // specified, then replace it with the existing recent task.
4213                task = tr;
4214            }
4215            notifyTaskPersisterLocked(tr, false);
4216        }
4217
4218        return -1;
4219    }
4220
4221    @Override
4222    public void reportActivityFullyDrawn(IBinder token) {
4223        synchronized (this) {
4224            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4225            if (r == null) {
4226                return;
4227            }
4228            r.reportFullyDrawnLocked();
4229        }
4230    }
4231
4232    @Override
4233    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4234        synchronized (this) {
4235            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4236            if (r == null) {
4237                return;
4238            }
4239            final long origId = Binder.clearCallingIdentity();
4240            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4241            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4242                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4243            if (config != null) {
4244                r.frozenBeforeDestroy = true;
4245                if (!updateConfigurationLocked(config, r, false, false)) {
4246                    mStackSupervisor.resumeTopActivitiesLocked();
4247                }
4248            }
4249            Binder.restoreCallingIdentity(origId);
4250        }
4251    }
4252
4253    @Override
4254    public int getRequestedOrientation(IBinder token) {
4255        synchronized (this) {
4256            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4257            if (r == null) {
4258                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4259            }
4260            return mWindowManager.getAppOrientation(r.appToken);
4261        }
4262    }
4263
4264    /**
4265     * This is the internal entry point for handling Activity.finish().
4266     *
4267     * @param token The Binder token referencing the Activity we want to finish.
4268     * @param resultCode Result code, if any, from this Activity.
4269     * @param resultData Result data (Intent), if any, from this Activity.
4270     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4271     *            the root Activity in the task.
4272     *
4273     * @return Returns true if the activity successfully finished, or false if it is still running.
4274     */
4275    @Override
4276    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4277            boolean finishTask) {
4278        // Refuse possible leaked file descriptors
4279        if (resultData != null && resultData.hasFileDescriptors() == true) {
4280            throw new IllegalArgumentException("File descriptors passed in Intent");
4281        }
4282
4283        synchronized(this) {
4284            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4285            if (r == null) {
4286                return true;
4287            }
4288            // Keep track of the root activity of the task before we finish it
4289            TaskRecord tr = r.task;
4290            ActivityRecord rootR = tr.getRootActivity();
4291            if (rootR == null) {
4292                Slog.w(TAG, "Finishing task with all activities already finished");
4293            }
4294            // Do not allow task to finish in Lock Task mode.
4295            if (tr == mStackSupervisor.mLockTaskModeTask) {
4296                if (rootR == r) {
4297                    Slog.i(TAG, "Not finishing task in lock task mode");
4298                    mStackSupervisor.showLockTaskToast();
4299                    return false;
4300                }
4301            }
4302            if (mController != null) {
4303                // Find the first activity that is not finishing.
4304                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4305                if (next != null) {
4306                    // ask watcher if this is allowed
4307                    boolean resumeOK = true;
4308                    try {
4309                        resumeOK = mController.activityResuming(next.packageName);
4310                    } catch (RemoteException e) {
4311                        mController = null;
4312                        Watchdog.getInstance().setActivityController(null);
4313                    }
4314
4315                    if (!resumeOK) {
4316                        Slog.i(TAG, "Not finishing activity because controller resumed");
4317                        return false;
4318                    }
4319                }
4320            }
4321            final long origId = Binder.clearCallingIdentity();
4322            try {
4323                boolean res;
4324                if (finishTask && r == rootR) {
4325                    // If requested, remove the task that is associated to this activity only if it
4326                    // was the root activity in the task. The result code and data is ignored
4327                    // because we don't support returning them across task boundaries.
4328                    res = removeTaskByIdLocked(tr.taskId, false);
4329                    if (!res) {
4330                        Slog.i(TAG, "Removing task failed to finish activity");
4331                    }
4332                } else {
4333                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4334                            resultData, "app-request", true);
4335                    if (!res) {
4336                        Slog.i(TAG, "Failed to finish by app-request");
4337                    }
4338                }
4339                return res;
4340            } finally {
4341                Binder.restoreCallingIdentity(origId);
4342            }
4343        }
4344    }
4345
4346    @Override
4347    public final void finishHeavyWeightApp() {
4348        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4349                != PackageManager.PERMISSION_GRANTED) {
4350            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4351                    + Binder.getCallingPid()
4352                    + ", uid=" + Binder.getCallingUid()
4353                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4354            Slog.w(TAG, msg);
4355            throw new SecurityException(msg);
4356        }
4357
4358        synchronized(this) {
4359            if (mHeavyWeightProcess == null) {
4360                return;
4361            }
4362
4363            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4364                    mHeavyWeightProcess.activities);
4365            for (int i=0; i<activities.size(); i++) {
4366                ActivityRecord r = activities.get(i);
4367                if (!r.finishing) {
4368                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4369                            null, "finish-heavy", true);
4370                }
4371            }
4372
4373            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4374                    mHeavyWeightProcess.userId, 0));
4375            mHeavyWeightProcess = null;
4376        }
4377    }
4378
4379    @Override
4380    public void crashApplication(int uid, int initialPid, String packageName,
4381            String message) {
4382        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4383                != PackageManager.PERMISSION_GRANTED) {
4384            String msg = "Permission Denial: crashApplication() from pid="
4385                    + Binder.getCallingPid()
4386                    + ", uid=" + Binder.getCallingUid()
4387                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4388            Slog.w(TAG, msg);
4389            throw new SecurityException(msg);
4390        }
4391
4392        synchronized(this) {
4393            ProcessRecord proc = null;
4394
4395            // Figure out which process to kill.  We don't trust that initialPid
4396            // still has any relation to current pids, so must scan through the
4397            // list.
4398            synchronized (mPidsSelfLocked) {
4399                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4400                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4401                    if (p.uid != uid) {
4402                        continue;
4403                    }
4404                    if (p.pid == initialPid) {
4405                        proc = p;
4406                        break;
4407                    }
4408                    if (p.pkgList.containsKey(packageName)) {
4409                        proc = p;
4410                    }
4411                }
4412            }
4413
4414            if (proc == null) {
4415                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4416                        + " initialPid=" + initialPid
4417                        + " packageName=" + packageName);
4418                return;
4419            }
4420
4421            if (proc.thread != null) {
4422                if (proc.pid == Process.myPid()) {
4423                    Log.w(TAG, "crashApplication: trying to crash self!");
4424                    return;
4425                }
4426                long ident = Binder.clearCallingIdentity();
4427                try {
4428                    proc.thread.scheduleCrash(message);
4429                } catch (RemoteException e) {
4430                }
4431                Binder.restoreCallingIdentity(ident);
4432            }
4433        }
4434    }
4435
4436    @Override
4437    public final void finishSubActivity(IBinder token, String resultWho,
4438            int requestCode) {
4439        synchronized(this) {
4440            final long origId = Binder.clearCallingIdentity();
4441            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4442            if (r != null) {
4443                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4444            }
4445            Binder.restoreCallingIdentity(origId);
4446        }
4447    }
4448
4449    @Override
4450    public boolean finishActivityAffinity(IBinder token) {
4451        synchronized(this) {
4452            final long origId = Binder.clearCallingIdentity();
4453            try {
4454                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4455
4456                ActivityRecord rootR = r.task.getRootActivity();
4457                // Do not allow task to finish in Lock Task mode.
4458                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4459                    if (rootR == r) {
4460                        mStackSupervisor.showLockTaskToast();
4461                        return false;
4462                    }
4463                }
4464                boolean res = false;
4465                if (r != null) {
4466                    res = r.task.stack.finishActivityAffinityLocked(r);
4467                }
4468                return res;
4469            } finally {
4470                Binder.restoreCallingIdentity(origId);
4471            }
4472        }
4473    }
4474
4475    @Override
4476    public void finishVoiceTask(IVoiceInteractionSession session) {
4477        synchronized(this) {
4478            final long origId = Binder.clearCallingIdentity();
4479            try {
4480                mStackSupervisor.finishVoiceTask(session);
4481            } finally {
4482                Binder.restoreCallingIdentity(origId);
4483            }
4484        }
4485
4486    }
4487
4488    @Override
4489    public boolean releaseActivityInstance(IBinder token) {
4490        synchronized(this) {
4491            final long origId = Binder.clearCallingIdentity();
4492            try {
4493                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4494                if (r.task == null || r.task.stack == null) {
4495                    return false;
4496                }
4497                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4498            } finally {
4499                Binder.restoreCallingIdentity(origId);
4500            }
4501        }
4502    }
4503
4504    @Override
4505    public void releaseSomeActivities(IApplicationThread appInt) {
4506        synchronized(this) {
4507            final long origId = Binder.clearCallingIdentity();
4508            try {
4509                ProcessRecord app = getRecordForAppLocked(appInt);
4510                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4511            } finally {
4512                Binder.restoreCallingIdentity(origId);
4513            }
4514        }
4515    }
4516
4517    @Override
4518    public boolean willActivityBeVisible(IBinder token) {
4519        synchronized(this) {
4520            ActivityStack stack = ActivityRecord.getStackLocked(token);
4521            if (stack != null) {
4522                return stack.willActivityBeVisibleLocked(token);
4523            }
4524            return false;
4525        }
4526    }
4527
4528    @Override
4529    public void overridePendingTransition(IBinder token, String packageName,
4530            int enterAnim, int exitAnim) {
4531        synchronized(this) {
4532            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4533            if (self == null) {
4534                return;
4535            }
4536
4537            final long origId = Binder.clearCallingIdentity();
4538
4539            if (self.state == ActivityState.RESUMED
4540                    || self.state == ActivityState.PAUSING) {
4541                mWindowManager.overridePendingAppTransition(packageName,
4542                        enterAnim, exitAnim, null);
4543            }
4544
4545            Binder.restoreCallingIdentity(origId);
4546        }
4547    }
4548
4549    /**
4550     * Main function for removing an existing process from the activity manager
4551     * as a result of that process going away.  Clears out all connections
4552     * to the process.
4553     */
4554    private final void handleAppDiedLocked(ProcessRecord app,
4555            boolean restarting, boolean allowRestart) {
4556        int pid = app.pid;
4557        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4558        if (!kept && !restarting) {
4559            removeLruProcessLocked(app);
4560            if (pid > 0) {
4561                ProcessList.remove(pid);
4562            }
4563        }
4564
4565        if (mProfileProc == app) {
4566            clearProfilerLocked();
4567        }
4568
4569        // Remove this application's activities from active lists.
4570        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4571
4572        app.activities.clear();
4573
4574        if (app.instrumentationClass != null) {
4575            Slog.w(TAG, "Crash of app " + app.processName
4576                  + " running instrumentation " + app.instrumentationClass);
4577            Bundle info = new Bundle();
4578            info.putString("shortMsg", "Process crashed.");
4579            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4580        }
4581
4582        if (!restarting) {
4583            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4584                // If there was nothing to resume, and we are not already
4585                // restarting this process, but there is a visible activity that
4586                // is hosted by the process...  then make sure all visible
4587                // activities are running, taking care of restarting this
4588                // process.
4589                if (hasVisibleActivities) {
4590                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4591                }
4592            }
4593        }
4594    }
4595
4596    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4597        IBinder threadBinder = thread.asBinder();
4598        // Find the application record.
4599        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4600            ProcessRecord rec = mLruProcesses.get(i);
4601            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4602                return i;
4603            }
4604        }
4605        return -1;
4606    }
4607
4608    final ProcessRecord getRecordForAppLocked(
4609            IApplicationThread thread) {
4610        if (thread == null) {
4611            return null;
4612        }
4613
4614        int appIndex = getLRURecordIndexForAppLocked(thread);
4615        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4616    }
4617
4618    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4619        // If there are no longer any background processes running,
4620        // and the app that died was not running instrumentation,
4621        // then tell everyone we are now low on memory.
4622        boolean haveBg = false;
4623        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4624            ProcessRecord rec = mLruProcesses.get(i);
4625            if (rec.thread != null
4626                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4627                haveBg = true;
4628                break;
4629            }
4630        }
4631
4632        if (!haveBg) {
4633            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4634            if (doReport) {
4635                long now = SystemClock.uptimeMillis();
4636                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4637                    doReport = false;
4638                } else {
4639                    mLastMemUsageReportTime = now;
4640                }
4641            }
4642            final ArrayList<ProcessMemInfo> memInfos
4643                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4644            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4645            long now = SystemClock.uptimeMillis();
4646            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4647                ProcessRecord rec = mLruProcesses.get(i);
4648                if (rec == dyingProc || rec.thread == null) {
4649                    continue;
4650                }
4651                if (doReport) {
4652                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4653                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4654                }
4655                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4656                    // The low memory report is overriding any current
4657                    // state for a GC request.  Make sure to do
4658                    // heavy/important/visible/foreground processes first.
4659                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4660                        rec.lastRequestedGc = 0;
4661                    } else {
4662                        rec.lastRequestedGc = rec.lastLowMemory;
4663                    }
4664                    rec.reportLowMemory = true;
4665                    rec.lastLowMemory = now;
4666                    mProcessesToGc.remove(rec);
4667                    addProcessToGcListLocked(rec);
4668                }
4669            }
4670            if (doReport) {
4671                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4672                mHandler.sendMessage(msg);
4673            }
4674            scheduleAppGcsLocked();
4675        }
4676    }
4677
4678    final void appDiedLocked(ProcessRecord app) {
4679       appDiedLocked(app, app.pid, app.thread);
4680    }
4681
4682    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4683        // First check if this ProcessRecord is actually active for the pid.
4684        synchronized (mPidsSelfLocked) {
4685            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4686            if (curProc != app) {
4687                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4688                return;
4689            }
4690        }
4691
4692        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4693        synchronized (stats) {
4694            stats.noteProcessDiedLocked(app.info.uid, pid);
4695        }
4696
4697        Process.killProcessQuiet(pid);
4698        Process.killProcessGroup(app.info.uid, pid);
4699        app.killed = true;
4700
4701        // Clean up already done if the process has been re-started.
4702        if (app.pid == pid && app.thread != null &&
4703                app.thread.asBinder() == thread.asBinder()) {
4704            boolean doLowMem = app.instrumentationClass == null;
4705            boolean doOomAdj = doLowMem;
4706            if (!app.killedByAm) {
4707                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4708                        + ") has died");
4709                mAllowLowerMemLevel = true;
4710            } else {
4711                // Note that we always want to do oom adj to update our state with the
4712                // new number of procs.
4713                mAllowLowerMemLevel = false;
4714                doLowMem = false;
4715            }
4716            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4717            if (DEBUG_CLEANUP) Slog.v(
4718                TAG, "Dying app: " + app + ", pid: " + pid
4719                + ", thread: " + thread.asBinder());
4720            handleAppDiedLocked(app, false, true);
4721
4722            if (doOomAdj) {
4723                updateOomAdjLocked();
4724            }
4725            if (doLowMem) {
4726                doLowMemReportIfNeededLocked(app);
4727            }
4728        } else if (app.pid != pid) {
4729            // A new process has already been started.
4730            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4731                    + ") has died and restarted (pid " + app.pid + ").");
4732            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4733        } else if (DEBUG_PROCESSES) {
4734            Slog.d(TAG, "Received spurious death notification for thread "
4735                    + thread.asBinder());
4736        }
4737    }
4738
4739    /**
4740     * If a stack trace dump file is configured, dump process stack traces.
4741     * @param clearTraces causes the dump file to be erased prior to the new
4742     *    traces being written, if true; when false, the new traces will be
4743     *    appended to any existing file content.
4744     * @param firstPids of dalvik VM processes to dump stack traces for first
4745     * @param lastPids of dalvik VM processes to dump stack traces for last
4746     * @param nativeProcs optional list of native process names to dump stack crawls
4747     * @return file containing stack traces, or null if no dump file is configured
4748     */
4749    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4750            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4751        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4752        if (tracesPath == null || tracesPath.length() == 0) {
4753            return null;
4754        }
4755
4756        File tracesFile = new File(tracesPath);
4757        try {
4758            File tracesDir = tracesFile.getParentFile();
4759            if (!tracesDir.exists()) {
4760                tracesDir.mkdirs();
4761                if (!SELinux.restorecon(tracesDir)) {
4762                    return null;
4763                }
4764            }
4765            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4766
4767            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4768            tracesFile.createNewFile();
4769            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4770        } catch (IOException e) {
4771            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4772            return null;
4773        }
4774
4775        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4776        return tracesFile;
4777    }
4778
4779    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4780            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4781        // Use a FileObserver to detect when traces finish writing.
4782        // The order of traces is considered important to maintain for legibility.
4783        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4784            @Override
4785            public synchronized void onEvent(int event, String path) { notify(); }
4786        };
4787
4788        try {
4789            observer.startWatching();
4790
4791            // First collect all of the stacks of the most important pids.
4792            if (firstPids != null) {
4793                try {
4794                    int num = firstPids.size();
4795                    for (int i = 0; i < num; i++) {
4796                        synchronized (observer) {
4797                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4798                            observer.wait(200);  // Wait for write-close, give up after 200msec
4799                        }
4800                    }
4801                } catch (InterruptedException e) {
4802                    Slog.wtf(TAG, e);
4803                }
4804            }
4805
4806            // Next collect the stacks of the native pids
4807            if (nativeProcs != null) {
4808                int[] pids = Process.getPidsForCommands(nativeProcs);
4809                if (pids != null) {
4810                    for (int pid : pids) {
4811                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4812                    }
4813                }
4814            }
4815
4816            // Lastly, measure CPU usage.
4817            if (processCpuTracker != null) {
4818                processCpuTracker.init();
4819                System.gc();
4820                processCpuTracker.update();
4821                try {
4822                    synchronized (processCpuTracker) {
4823                        processCpuTracker.wait(500); // measure over 1/2 second.
4824                    }
4825                } catch (InterruptedException e) {
4826                }
4827                processCpuTracker.update();
4828
4829                // We'll take the stack crawls of just the top apps using CPU.
4830                final int N = processCpuTracker.countWorkingStats();
4831                int numProcs = 0;
4832                for (int i=0; i<N && numProcs<5; i++) {
4833                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4834                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4835                        numProcs++;
4836                        try {
4837                            synchronized (observer) {
4838                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4839                                observer.wait(200);  // Wait for write-close, give up after 200msec
4840                            }
4841                        } catch (InterruptedException e) {
4842                            Slog.wtf(TAG, e);
4843                        }
4844
4845                    }
4846                }
4847            }
4848        } finally {
4849            observer.stopWatching();
4850        }
4851    }
4852
4853    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4854        if (true || IS_USER_BUILD) {
4855            return;
4856        }
4857        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4858        if (tracesPath == null || tracesPath.length() == 0) {
4859            return;
4860        }
4861
4862        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4863        StrictMode.allowThreadDiskWrites();
4864        try {
4865            final File tracesFile = new File(tracesPath);
4866            final File tracesDir = tracesFile.getParentFile();
4867            final File tracesTmp = new File(tracesDir, "__tmp__");
4868            try {
4869                if (!tracesDir.exists()) {
4870                    tracesDir.mkdirs();
4871                    if (!SELinux.restorecon(tracesDir.getPath())) {
4872                        return;
4873                    }
4874                }
4875                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4876
4877                if (tracesFile.exists()) {
4878                    tracesTmp.delete();
4879                    tracesFile.renameTo(tracesTmp);
4880                }
4881                StringBuilder sb = new StringBuilder();
4882                Time tobj = new Time();
4883                tobj.set(System.currentTimeMillis());
4884                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4885                sb.append(": ");
4886                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4887                sb.append(" since ");
4888                sb.append(msg);
4889                FileOutputStream fos = new FileOutputStream(tracesFile);
4890                fos.write(sb.toString().getBytes());
4891                if (app == null) {
4892                    fos.write("\n*** No application process!".getBytes());
4893                }
4894                fos.close();
4895                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4896            } catch (IOException e) {
4897                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4898                return;
4899            }
4900
4901            if (app != null) {
4902                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4903                firstPids.add(app.pid);
4904                dumpStackTraces(tracesPath, firstPids, null, null, null);
4905            }
4906
4907            File lastTracesFile = null;
4908            File curTracesFile = null;
4909            for (int i=9; i>=0; i--) {
4910                String name = String.format(Locale.US, "slow%02d.txt", i);
4911                curTracesFile = new File(tracesDir, name);
4912                if (curTracesFile.exists()) {
4913                    if (lastTracesFile != null) {
4914                        curTracesFile.renameTo(lastTracesFile);
4915                    } else {
4916                        curTracesFile.delete();
4917                    }
4918                }
4919                lastTracesFile = curTracesFile;
4920            }
4921            tracesFile.renameTo(curTracesFile);
4922            if (tracesTmp.exists()) {
4923                tracesTmp.renameTo(tracesFile);
4924            }
4925        } finally {
4926            StrictMode.setThreadPolicy(oldPolicy);
4927        }
4928    }
4929
4930    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4931            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4932        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4933        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4934
4935        if (mController != null) {
4936            try {
4937                // 0 == continue, -1 = kill process immediately
4938                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4939                if (res < 0 && app.pid != MY_PID) {
4940                    app.kill("anr", true);
4941                }
4942            } catch (RemoteException e) {
4943                mController = null;
4944                Watchdog.getInstance().setActivityController(null);
4945            }
4946        }
4947
4948        long anrTime = SystemClock.uptimeMillis();
4949        if (MONITOR_CPU_USAGE) {
4950            updateCpuStatsNow();
4951        }
4952
4953        synchronized (this) {
4954            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4955            if (mShuttingDown) {
4956                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4957                return;
4958            } else if (app.notResponding) {
4959                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4960                return;
4961            } else if (app.crashing) {
4962                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4963                return;
4964            }
4965
4966            // In case we come through here for the same app before completing
4967            // this one, mark as anring now so we will bail out.
4968            app.notResponding = true;
4969
4970            // Log the ANR to the event log.
4971            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4972                    app.processName, app.info.flags, annotation);
4973
4974            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4975            firstPids.add(app.pid);
4976
4977            int parentPid = app.pid;
4978            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4979            if (parentPid != app.pid) firstPids.add(parentPid);
4980
4981            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4982
4983            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4984                ProcessRecord r = mLruProcesses.get(i);
4985                if (r != null && r.thread != null) {
4986                    int pid = r.pid;
4987                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4988                        if (r.persistent) {
4989                            firstPids.add(pid);
4990                        } else {
4991                            lastPids.put(pid, Boolean.TRUE);
4992                        }
4993                    }
4994                }
4995            }
4996        }
4997
4998        // Log the ANR to the main log.
4999        StringBuilder info = new StringBuilder();
5000        info.setLength(0);
5001        info.append("ANR in ").append(app.processName);
5002        if (activity != null && activity.shortComponentName != null) {
5003            info.append(" (").append(activity.shortComponentName).append(")");
5004        }
5005        info.append("\n");
5006        info.append("PID: ").append(app.pid).append("\n");
5007        if (annotation != null) {
5008            info.append("Reason: ").append(annotation).append("\n");
5009        }
5010        if (parent != null && parent != activity) {
5011            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5012        }
5013
5014        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5015
5016        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5017                NATIVE_STACKS_OF_INTEREST);
5018
5019        String cpuInfo = null;
5020        if (MONITOR_CPU_USAGE) {
5021            updateCpuStatsNow();
5022            synchronized (mProcessCpuTracker) {
5023                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5024            }
5025            info.append(processCpuTracker.printCurrentLoad());
5026            info.append(cpuInfo);
5027        }
5028
5029        info.append(processCpuTracker.printCurrentState(anrTime));
5030
5031        Slog.e(TAG, info.toString());
5032        if (tracesFile == null) {
5033            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5034            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5035        }
5036
5037        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5038                cpuInfo, tracesFile, null);
5039
5040        if (mController != null) {
5041            try {
5042                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5043                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5044                if (res != 0) {
5045                    if (res < 0 && app.pid != MY_PID) {
5046                        app.kill("anr", true);
5047                    } else {
5048                        synchronized (this) {
5049                            mServices.scheduleServiceTimeoutLocked(app);
5050                        }
5051                    }
5052                    return;
5053                }
5054            } catch (RemoteException e) {
5055                mController = null;
5056                Watchdog.getInstance().setActivityController(null);
5057            }
5058        }
5059
5060        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5061        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5062                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5063
5064        synchronized (this) {
5065            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5066                app.kill("bg anr", true);
5067                return;
5068            }
5069
5070            // Set the app's notResponding state, and look up the errorReportReceiver
5071            makeAppNotRespondingLocked(app,
5072                    activity != null ? activity.shortComponentName : null,
5073                    annotation != null ? "ANR " + annotation : "ANR",
5074                    info.toString());
5075
5076            // Bring up the infamous App Not Responding dialog
5077            Message msg = Message.obtain();
5078            HashMap<String, Object> map = new HashMap<String, Object>();
5079            msg.what = SHOW_NOT_RESPONDING_MSG;
5080            msg.obj = map;
5081            msg.arg1 = aboveSystem ? 1 : 0;
5082            map.put("app", app);
5083            if (activity != null) {
5084                map.put("activity", activity);
5085            }
5086
5087            mHandler.sendMessage(msg);
5088        }
5089    }
5090
5091    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5092        if (!mLaunchWarningShown) {
5093            mLaunchWarningShown = true;
5094            mHandler.post(new Runnable() {
5095                @Override
5096                public void run() {
5097                    synchronized (ActivityManagerService.this) {
5098                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5099                        d.show();
5100                        mHandler.postDelayed(new Runnable() {
5101                            @Override
5102                            public void run() {
5103                                synchronized (ActivityManagerService.this) {
5104                                    d.dismiss();
5105                                    mLaunchWarningShown = false;
5106                                }
5107                            }
5108                        }, 4000);
5109                    }
5110                }
5111            });
5112        }
5113    }
5114
5115    @Override
5116    public boolean clearApplicationUserData(final String packageName,
5117            final IPackageDataObserver observer, int userId) {
5118        enforceNotIsolatedCaller("clearApplicationUserData");
5119        int uid = Binder.getCallingUid();
5120        int pid = Binder.getCallingPid();
5121        userId = handleIncomingUser(pid, uid,
5122                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5123        long callingId = Binder.clearCallingIdentity();
5124        try {
5125            IPackageManager pm = AppGlobals.getPackageManager();
5126            int pkgUid = -1;
5127            synchronized(this) {
5128                try {
5129                    pkgUid = pm.getPackageUid(packageName, userId);
5130                } catch (RemoteException e) {
5131                }
5132                if (pkgUid == -1) {
5133                    Slog.w(TAG, "Invalid packageName: " + packageName);
5134                    if (observer != null) {
5135                        try {
5136                            observer.onRemoveCompleted(packageName, false);
5137                        } catch (RemoteException e) {
5138                            Slog.i(TAG, "Observer no longer exists.");
5139                        }
5140                    }
5141                    return false;
5142                }
5143                if (uid == pkgUid || checkComponentPermission(
5144                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5145                        pid, uid, -1, true)
5146                        == PackageManager.PERMISSION_GRANTED) {
5147                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5148                } else {
5149                    throw new SecurityException("PID " + pid + " does not have permission "
5150                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5151                                    + " of package " + packageName);
5152                }
5153
5154                // Remove all tasks match the cleared application package and user
5155                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5156                    final TaskRecord tr = mRecentTasks.get(i);
5157                    final String taskPackageName =
5158                            tr.getBaseIntent().getComponent().getPackageName();
5159                    if (tr.userId != userId) continue;
5160                    if (!taskPackageName.equals(packageName)) continue;
5161                    removeTaskByIdLocked(tr.taskId, false);
5162                }
5163            }
5164
5165            try {
5166                // Clear application user data
5167                pm.clearApplicationUserData(packageName, observer, userId);
5168
5169                synchronized(this) {
5170                    // Remove all permissions granted from/to this package
5171                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5172                }
5173
5174                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5175                        Uri.fromParts("package", packageName, null));
5176                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5177                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5178                        null, null, 0, null, null, null, false, false, userId);
5179            } catch (RemoteException e) {
5180            }
5181        } finally {
5182            Binder.restoreCallingIdentity(callingId);
5183        }
5184        return true;
5185    }
5186
5187    @Override
5188    public void killBackgroundProcesses(final String packageName, int userId) {
5189        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5190                != PackageManager.PERMISSION_GRANTED &&
5191                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5192                        != PackageManager.PERMISSION_GRANTED) {
5193            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5194                    + Binder.getCallingPid()
5195                    + ", uid=" + Binder.getCallingUid()
5196                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5197            Slog.w(TAG, msg);
5198            throw new SecurityException(msg);
5199        }
5200
5201        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5202                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5203        long callingId = Binder.clearCallingIdentity();
5204        try {
5205            IPackageManager pm = AppGlobals.getPackageManager();
5206            synchronized(this) {
5207                int appId = -1;
5208                try {
5209                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5210                } catch (RemoteException e) {
5211                }
5212                if (appId == -1) {
5213                    Slog.w(TAG, "Invalid packageName: " + packageName);
5214                    return;
5215                }
5216                killPackageProcessesLocked(packageName, appId, userId,
5217                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5218            }
5219        } finally {
5220            Binder.restoreCallingIdentity(callingId);
5221        }
5222    }
5223
5224    @Override
5225    public void killAllBackgroundProcesses() {
5226        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5227                != PackageManager.PERMISSION_GRANTED) {
5228            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5229                    + Binder.getCallingPid()
5230                    + ", uid=" + Binder.getCallingUid()
5231                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5232            Slog.w(TAG, msg);
5233            throw new SecurityException(msg);
5234        }
5235
5236        long callingId = Binder.clearCallingIdentity();
5237        try {
5238            synchronized(this) {
5239                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5240                final int NP = mProcessNames.getMap().size();
5241                for (int ip=0; ip<NP; ip++) {
5242                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5243                    final int NA = apps.size();
5244                    for (int ia=0; ia<NA; ia++) {
5245                        ProcessRecord app = apps.valueAt(ia);
5246                        if (app.persistent) {
5247                            // we don't kill persistent processes
5248                            continue;
5249                        }
5250                        if (app.removed) {
5251                            procs.add(app);
5252                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5253                            app.removed = true;
5254                            procs.add(app);
5255                        }
5256                    }
5257                }
5258
5259                int N = procs.size();
5260                for (int i=0; i<N; i++) {
5261                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5262                }
5263                mAllowLowerMemLevel = true;
5264                updateOomAdjLocked();
5265                doLowMemReportIfNeededLocked(null);
5266            }
5267        } finally {
5268            Binder.restoreCallingIdentity(callingId);
5269        }
5270    }
5271
5272    @Override
5273    public void forceStopPackage(final String packageName, int userId) {
5274        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5275                != PackageManager.PERMISSION_GRANTED) {
5276            String msg = "Permission Denial: forceStopPackage() from pid="
5277                    + Binder.getCallingPid()
5278                    + ", uid=" + Binder.getCallingUid()
5279                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5280            Slog.w(TAG, msg);
5281            throw new SecurityException(msg);
5282        }
5283        final int callingPid = Binder.getCallingPid();
5284        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5285                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5286        long callingId = Binder.clearCallingIdentity();
5287        try {
5288            IPackageManager pm = AppGlobals.getPackageManager();
5289            synchronized(this) {
5290                int[] users = userId == UserHandle.USER_ALL
5291                        ? getUsersLocked() : new int[] { userId };
5292                for (int user : users) {
5293                    int pkgUid = -1;
5294                    try {
5295                        pkgUid = pm.getPackageUid(packageName, user);
5296                    } catch (RemoteException e) {
5297                    }
5298                    if (pkgUid == -1) {
5299                        Slog.w(TAG, "Invalid packageName: " + packageName);
5300                        continue;
5301                    }
5302                    try {
5303                        pm.setPackageStoppedState(packageName, true, user);
5304                    } catch (RemoteException e) {
5305                    } catch (IllegalArgumentException e) {
5306                        Slog.w(TAG, "Failed trying to unstop package "
5307                                + packageName + ": " + e);
5308                    }
5309                    if (isUserRunningLocked(user, false)) {
5310                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5311                    }
5312                }
5313            }
5314        } finally {
5315            Binder.restoreCallingIdentity(callingId);
5316        }
5317    }
5318
5319    @Override
5320    public void addPackageDependency(String packageName) {
5321        synchronized (this) {
5322            int callingPid = Binder.getCallingPid();
5323            if (callingPid == Process.myPid()) {
5324                //  Yeah, um, no.
5325                Slog.w(TAG, "Can't addPackageDependency on system process");
5326                return;
5327            }
5328            ProcessRecord proc;
5329            synchronized (mPidsSelfLocked) {
5330                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5331            }
5332            if (proc != null) {
5333                if (proc.pkgDeps == null) {
5334                    proc.pkgDeps = new ArraySet<String>(1);
5335                }
5336                proc.pkgDeps.add(packageName);
5337            }
5338        }
5339    }
5340
5341    /*
5342     * The pkg name and app id have to be specified.
5343     */
5344    @Override
5345    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5346        if (pkg == null) {
5347            return;
5348        }
5349        // Make sure the uid is valid.
5350        if (appid < 0) {
5351            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5352            return;
5353        }
5354        int callerUid = Binder.getCallingUid();
5355        // Only the system server can kill an application
5356        if (callerUid == Process.SYSTEM_UID) {
5357            // Post an aysnc message to kill the application
5358            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5359            msg.arg1 = appid;
5360            msg.arg2 = 0;
5361            Bundle bundle = new Bundle();
5362            bundle.putString("pkg", pkg);
5363            bundle.putString("reason", reason);
5364            msg.obj = bundle;
5365            mHandler.sendMessage(msg);
5366        } else {
5367            throw new SecurityException(callerUid + " cannot kill pkg: " +
5368                    pkg);
5369        }
5370    }
5371
5372    @Override
5373    public void closeSystemDialogs(String reason) {
5374        enforceNotIsolatedCaller("closeSystemDialogs");
5375
5376        final int pid = Binder.getCallingPid();
5377        final int uid = Binder.getCallingUid();
5378        final long origId = Binder.clearCallingIdentity();
5379        try {
5380            synchronized (this) {
5381                // Only allow this from foreground processes, so that background
5382                // applications can't abuse it to prevent system UI from being shown.
5383                if (uid >= Process.FIRST_APPLICATION_UID) {
5384                    ProcessRecord proc;
5385                    synchronized (mPidsSelfLocked) {
5386                        proc = mPidsSelfLocked.get(pid);
5387                    }
5388                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5389                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5390                                + " from background process " + proc);
5391                        return;
5392                    }
5393                }
5394                closeSystemDialogsLocked(reason);
5395            }
5396        } finally {
5397            Binder.restoreCallingIdentity(origId);
5398        }
5399    }
5400
5401    void closeSystemDialogsLocked(String reason) {
5402        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5403        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5404                | Intent.FLAG_RECEIVER_FOREGROUND);
5405        if (reason != null) {
5406            intent.putExtra("reason", reason);
5407        }
5408        mWindowManager.closeSystemDialogs(reason);
5409
5410        mStackSupervisor.closeSystemDialogsLocked();
5411
5412        broadcastIntentLocked(null, null, intent, null,
5413                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5414                Process.SYSTEM_UID, UserHandle.USER_ALL);
5415    }
5416
5417    @Override
5418    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5419        enforceNotIsolatedCaller("getProcessMemoryInfo");
5420        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5421        for (int i=pids.length-1; i>=0; i--) {
5422            ProcessRecord proc;
5423            int oomAdj;
5424            synchronized (this) {
5425                synchronized (mPidsSelfLocked) {
5426                    proc = mPidsSelfLocked.get(pids[i]);
5427                    oomAdj = proc != null ? proc.setAdj : 0;
5428                }
5429            }
5430            infos[i] = new Debug.MemoryInfo();
5431            Debug.getMemoryInfo(pids[i], infos[i]);
5432            if (proc != null) {
5433                synchronized (this) {
5434                    if (proc.thread != null && proc.setAdj == oomAdj) {
5435                        // Record this for posterity if the process has been stable.
5436                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5437                                infos[i].getTotalUss(), false, proc.pkgList);
5438                    }
5439                }
5440            }
5441        }
5442        return infos;
5443    }
5444
5445    @Override
5446    public long[] getProcessPss(int[] pids) {
5447        enforceNotIsolatedCaller("getProcessPss");
5448        long[] pss = new long[pids.length];
5449        for (int i=pids.length-1; i>=0; i--) {
5450            ProcessRecord proc;
5451            int oomAdj;
5452            synchronized (this) {
5453                synchronized (mPidsSelfLocked) {
5454                    proc = mPidsSelfLocked.get(pids[i]);
5455                    oomAdj = proc != null ? proc.setAdj : 0;
5456                }
5457            }
5458            long[] tmpUss = new long[1];
5459            pss[i] = Debug.getPss(pids[i], tmpUss);
5460            if (proc != null) {
5461                synchronized (this) {
5462                    if (proc.thread != null && proc.setAdj == oomAdj) {
5463                        // Record this for posterity if the process has been stable.
5464                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5465                    }
5466                }
5467            }
5468        }
5469        return pss;
5470    }
5471
5472    @Override
5473    public void killApplicationProcess(String processName, int uid) {
5474        if (processName == null) {
5475            return;
5476        }
5477
5478        int callerUid = Binder.getCallingUid();
5479        // Only the system server can kill an application
5480        if (callerUid == Process.SYSTEM_UID) {
5481            synchronized (this) {
5482                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5483                if (app != null && app.thread != null) {
5484                    try {
5485                        app.thread.scheduleSuicide();
5486                    } catch (RemoteException e) {
5487                        // If the other end already died, then our work here is done.
5488                    }
5489                } else {
5490                    Slog.w(TAG, "Process/uid not found attempting kill of "
5491                            + processName + " / " + uid);
5492                }
5493            }
5494        } else {
5495            throw new SecurityException(callerUid + " cannot kill app process: " +
5496                    processName);
5497        }
5498    }
5499
5500    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5501        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5502                false, true, false, false, UserHandle.getUserId(uid), reason);
5503        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5504                Uri.fromParts("package", packageName, null));
5505        if (!mProcessesReady) {
5506            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5507                    | Intent.FLAG_RECEIVER_FOREGROUND);
5508        }
5509        intent.putExtra(Intent.EXTRA_UID, uid);
5510        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5511        broadcastIntentLocked(null, null, intent,
5512                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5513                false, false,
5514                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5515    }
5516
5517    private void forceStopUserLocked(int userId, String reason) {
5518        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5519        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5520        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5521                | Intent.FLAG_RECEIVER_FOREGROUND);
5522        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5523        broadcastIntentLocked(null, null, intent,
5524                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5525                false, false,
5526                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5527    }
5528
5529    private final boolean killPackageProcessesLocked(String packageName, int appId,
5530            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5531            boolean doit, boolean evenPersistent, String reason) {
5532        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5533
5534        // Remove all processes this package may have touched: all with the
5535        // same UID (except for the system or root user), and all whose name
5536        // matches the package name.
5537        final int NP = mProcessNames.getMap().size();
5538        for (int ip=0; ip<NP; ip++) {
5539            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5540            final int NA = apps.size();
5541            for (int ia=0; ia<NA; ia++) {
5542                ProcessRecord app = apps.valueAt(ia);
5543                if (app.persistent && !evenPersistent) {
5544                    // we don't kill persistent processes
5545                    continue;
5546                }
5547                if (app.removed) {
5548                    if (doit) {
5549                        procs.add(app);
5550                    }
5551                    continue;
5552                }
5553
5554                // Skip process if it doesn't meet our oom adj requirement.
5555                if (app.setAdj < minOomAdj) {
5556                    continue;
5557                }
5558
5559                // If no package is specified, we call all processes under the
5560                // give user id.
5561                if (packageName == null) {
5562                    if (app.userId != userId) {
5563                        continue;
5564                    }
5565                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5566                        continue;
5567                    }
5568                // Package has been specified, we want to hit all processes
5569                // that match it.  We need to qualify this by the processes
5570                // that are running under the specified app and user ID.
5571                } else {
5572                    final boolean isDep = app.pkgDeps != null
5573                            && app.pkgDeps.contains(packageName);
5574                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5575                        continue;
5576                    }
5577                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5578                        continue;
5579                    }
5580                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5581                        continue;
5582                    }
5583                }
5584
5585                // Process has passed all conditions, kill it!
5586                if (!doit) {
5587                    return true;
5588                }
5589                app.removed = true;
5590                procs.add(app);
5591            }
5592        }
5593
5594        int N = procs.size();
5595        for (int i=0; i<N; i++) {
5596            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5597        }
5598        updateOomAdjLocked();
5599        return N > 0;
5600    }
5601
5602    private final boolean forceStopPackageLocked(String name, int appId,
5603            boolean callerWillRestart, boolean purgeCache, boolean doit,
5604            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5605        int i;
5606        int N;
5607
5608        if (userId == UserHandle.USER_ALL && name == null) {
5609            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5610        }
5611
5612        if (appId < 0 && name != null) {
5613            try {
5614                appId = UserHandle.getAppId(
5615                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5616            } catch (RemoteException e) {
5617            }
5618        }
5619
5620        if (doit) {
5621            if (name != null) {
5622                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5623                        + " user=" + userId + ": " + reason);
5624            } else {
5625                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5626            }
5627
5628            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5629            for (int ip=pmap.size()-1; ip>=0; ip--) {
5630                SparseArray<Long> ba = pmap.valueAt(ip);
5631                for (i=ba.size()-1; i>=0; i--) {
5632                    boolean remove = false;
5633                    final int entUid = ba.keyAt(i);
5634                    if (name != null) {
5635                        if (userId == UserHandle.USER_ALL) {
5636                            if (UserHandle.getAppId(entUid) == appId) {
5637                                remove = true;
5638                            }
5639                        } else {
5640                            if (entUid == UserHandle.getUid(userId, appId)) {
5641                                remove = true;
5642                            }
5643                        }
5644                    } else if (UserHandle.getUserId(entUid) == userId) {
5645                        remove = true;
5646                    }
5647                    if (remove) {
5648                        ba.removeAt(i);
5649                    }
5650                }
5651                if (ba.size() == 0) {
5652                    pmap.removeAt(ip);
5653                }
5654            }
5655        }
5656
5657        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5658                -100, callerWillRestart, true, doit, evenPersistent,
5659                name == null ? ("stop user " + userId) : ("stop " + name));
5660
5661        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5662            if (!doit) {
5663                return true;
5664            }
5665            didSomething = true;
5666        }
5667
5668        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5669            if (!doit) {
5670                return true;
5671            }
5672            didSomething = true;
5673        }
5674
5675        if (name == null) {
5676            // Remove all sticky broadcasts from this user.
5677            mStickyBroadcasts.remove(userId);
5678        }
5679
5680        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5681        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5682                userId, providers)) {
5683            if (!doit) {
5684                return true;
5685            }
5686            didSomething = true;
5687        }
5688        N = providers.size();
5689        for (i=0; i<N; i++) {
5690            removeDyingProviderLocked(null, providers.get(i), true);
5691        }
5692
5693        // Remove transient permissions granted from/to this package/user
5694        removeUriPermissionsForPackageLocked(name, userId, false);
5695
5696        if (name == null || uninstalling) {
5697            // Remove pending intents.  For now we only do this when force
5698            // stopping users, because we have some problems when doing this
5699            // for packages -- app widgets are not currently cleaned up for
5700            // such packages, so they can be left with bad pending intents.
5701            if (mIntentSenderRecords.size() > 0) {
5702                Iterator<WeakReference<PendingIntentRecord>> it
5703                        = mIntentSenderRecords.values().iterator();
5704                while (it.hasNext()) {
5705                    WeakReference<PendingIntentRecord> wpir = it.next();
5706                    if (wpir == null) {
5707                        it.remove();
5708                        continue;
5709                    }
5710                    PendingIntentRecord pir = wpir.get();
5711                    if (pir == null) {
5712                        it.remove();
5713                        continue;
5714                    }
5715                    if (name == null) {
5716                        // Stopping user, remove all objects for the user.
5717                        if (pir.key.userId != userId) {
5718                            // Not the same user, skip it.
5719                            continue;
5720                        }
5721                    } else {
5722                        if (UserHandle.getAppId(pir.uid) != appId) {
5723                            // Different app id, skip it.
5724                            continue;
5725                        }
5726                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5727                            // Different user, skip it.
5728                            continue;
5729                        }
5730                        if (!pir.key.packageName.equals(name)) {
5731                            // Different package, skip it.
5732                            continue;
5733                        }
5734                    }
5735                    if (!doit) {
5736                        return true;
5737                    }
5738                    didSomething = true;
5739                    it.remove();
5740                    pir.canceled = true;
5741                    if (pir.key.activity != null) {
5742                        pir.key.activity.pendingResults.remove(pir.ref);
5743                    }
5744                }
5745            }
5746        }
5747
5748        if (doit) {
5749            if (purgeCache && name != null) {
5750                AttributeCache ac = AttributeCache.instance();
5751                if (ac != null) {
5752                    ac.removePackage(name);
5753                }
5754            }
5755            if (mBooted) {
5756                mStackSupervisor.resumeTopActivitiesLocked();
5757                mStackSupervisor.scheduleIdleLocked();
5758            }
5759        }
5760
5761        return didSomething;
5762    }
5763
5764    private final boolean removeProcessLocked(ProcessRecord app,
5765            boolean callerWillRestart, boolean allowRestart, String reason) {
5766        final String name = app.processName;
5767        final int uid = app.uid;
5768        if (DEBUG_PROCESSES) Slog.d(
5769            TAG, "Force removing proc " + app.toShortString() + " (" + name
5770            + "/" + uid + ")");
5771
5772        mProcessNames.remove(name, uid);
5773        mIsolatedProcesses.remove(app.uid);
5774        if (mHeavyWeightProcess == app) {
5775            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5776                    mHeavyWeightProcess.userId, 0));
5777            mHeavyWeightProcess = null;
5778        }
5779        boolean needRestart = false;
5780        if (app.pid > 0 && app.pid != MY_PID) {
5781            int pid = app.pid;
5782            synchronized (mPidsSelfLocked) {
5783                mPidsSelfLocked.remove(pid);
5784                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5785            }
5786            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5787            if (app.isolated) {
5788                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5789            }
5790            app.kill(reason, true);
5791            handleAppDiedLocked(app, true, allowRestart);
5792            removeLruProcessLocked(app);
5793
5794            if (app.persistent && !app.isolated) {
5795                if (!callerWillRestart) {
5796                    addAppLocked(app.info, false, null /* ABI override */);
5797                } else {
5798                    needRestart = true;
5799                }
5800            }
5801        } else {
5802            mRemovedProcesses.add(app);
5803        }
5804
5805        return needRestart;
5806    }
5807
5808    private final void processStartTimedOutLocked(ProcessRecord app) {
5809        final int pid = app.pid;
5810        boolean gone = false;
5811        synchronized (mPidsSelfLocked) {
5812            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5813            if (knownApp != null && knownApp.thread == null) {
5814                mPidsSelfLocked.remove(pid);
5815                gone = true;
5816            }
5817        }
5818
5819        if (gone) {
5820            Slog.w(TAG, "Process " + app + " failed to attach");
5821            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5822                    pid, app.uid, app.processName);
5823            mProcessNames.remove(app.processName, app.uid);
5824            mIsolatedProcesses.remove(app.uid);
5825            if (mHeavyWeightProcess == app) {
5826                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5827                        mHeavyWeightProcess.userId, 0));
5828                mHeavyWeightProcess = null;
5829            }
5830            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5831            if (app.isolated) {
5832                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5833            }
5834            // Take care of any launching providers waiting for this process.
5835            checkAppInLaunchingProvidersLocked(app, true);
5836            // Take care of any services that are waiting for the process.
5837            mServices.processStartTimedOutLocked(app);
5838            app.kill("start timeout", true);
5839            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5840                Slog.w(TAG, "Unattached app died before backup, skipping");
5841                try {
5842                    IBackupManager bm = IBackupManager.Stub.asInterface(
5843                            ServiceManager.getService(Context.BACKUP_SERVICE));
5844                    bm.agentDisconnected(app.info.packageName);
5845                } catch (RemoteException e) {
5846                    // Can't happen; the backup manager is local
5847                }
5848            }
5849            if (isPendingBroadcastProcessLocked(pid)) {
5850                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5851                skipPendingBroadcastLocked(pid);
5852            }
5853        } else {
5854            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5855        }
5856    }
5857
5858    private final boolean attachApplicationLocked(IApplicationThread thread,
5859            int pid) {
5860
5861        // Find the application record that is being attached...  either via
5862        // the pid if we are running in multiple processes, or just pull the
5863        // next app record if we are emulating process with anonymous threads.
5864        ProcessRecord app;
5865        if (pid != MY_PID && pid >= 0) {
5866            synchronized (mPidsSelfLocked) {
5867                app = mPidsSelfLocked.get(pid);
5868            }
5869        } else {
5870            app = null;
5871        }
5872
5873        if (app == null) {
5874            Slog.w(TAG, "No pending application record for pid " + pid
5875                    + " (IApplicationThread " + thread + "); dropping process");
5876            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5877            if (pid > 0 && pid != MY_PID) {
5878                Process.killProcessQuiet(pid);
5879                //TODO: Process.killProcessGroup(app.info.uid, pid);
5880            } else {
5881                try {
5882                    thread.scheduleExit();
5883                } catch (Exception e) {
5884                    // Ignore exceptions.
5885                }
5886            }
5887            return false;
5888        }
5889
5890        // If this application record is still attached to a previous
5891        // process, clean it up now.
5892        if (app.thread != null) {
5893            handleAppDiedLocked(app, true, true);
5894        }
5895
5896        // Tell the process all about itself.
5897
5898        if (localLOGV) Slog.v(
5899                TAG, "Binding process pid " + pid + " to record " + app);
5900
5901        final String processName = app.processName;
5902        try {
5903            AppDeathRecipient adr = new AppDeathRecipient(
5904                    app, pid, thread);
5905            thread.asBinder().linkToDeath(adr, 0);
5906            app.deathRecipient = adr;
5907        } catch (RemoteException e) {
5908            app.resetPackageList(mProcessStats);
5909            startProcessLocked(app, "link fail", processName);
5910            return false;
5911        }
5912
5913        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5914
5915        app.makeActive(thread, mProcessStats);
5916        app.curAdj = app.setAdj = -100;
5917        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5918        app.forcingToForeground = null;
5919        updateProcessForegroundLocked(app, false, false);
5920        app.hasShownUi = false;
5921        app.debugging = false;
5922        app.cached = false;
5923
5924        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5925
5926        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5927        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5928
5929        if (!normalMode) {
5930            Slog.i(TAG, "Launching preboot mode app: " + app);
5931        }
5932
5933        if (localLOGV) Slog.v(
5934            TAG, "New app record " + app
5935            + " thread=" + thread.asBinder() + " pid=" + pid);
5936        try {
5937            int testMode = IApplicationThread.DEBUG_OFF;
5938            if (mDebugApp != null && mDebugApp.equals(processName)) {
5939                testMode = mWaitForDebugger
5940                    ? IApplicationThread.DEBUG_WAIT
5941                    : IApplicationThread.DEBUG_ON;
5942                app.debugging = true;
5943                if (mDebugTransient) {
5944                    mDebugApp = mOrigDebugApp;
5945                    mWaitForDebugger = mOrigWaitForDebugger;
5946                }
5947            }
5948            String profileFile = app.instrumentationProfileFile;
5949            ParcelFileDescriptor profileFd = null;
5950            int samplingInterval = 0;
5951            boolean profileAutoStop = false;
5952            if (mProfileApp != null && mProfileApp.equals(processName)) {
5953                mProfileProc = app;
5954                profileFile = mProfileFile;
5955                profileFd = mProfileFd;
5956                samplingInterval = mSamplingInterval;
5957                profileAutoStop = mAutoStopProfiler;
5958            }
5959            boolean enableOpenGlTrace = false;
5960            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5961                enableOpenGlTrace = true;
5962                mOpenGlTraceApp = null;
5963            }
5964
5965            // If the app is being launched for restore or full backup, set it up specially
5966            boolean isRestrictedBackupMode = false;
5967            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5968                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5969                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5970                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5971            }
5972
5973            ensurePackageDexOpt(app.instrumentationInfo != null
5974                    ? app.instrumentationInfo.packageName
5975                    : app.info.packageName);
5976            if (app.instrumentationClass != null) {
5977                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5978            }
5979            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5980                    + processName + " with config " + mConfiguration);
5981            ApplicationInfo appInfo = app.instrumentationInfo != null
5982                    ? app.instrumentationInfo : app.info;
5983            app.compat = compatibilityInfoForPackageLocked(appInfo);
5984            if (profileFd != null) {
5985                profileFd = profileFd.dup();
5986            }
5987            ProfilerInfo profilerInfo = profileFile == null ? null
5988                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5989            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5990                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5991                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5992                    isRestrictedBackupMode || !normalMode, app.persistent,
5993                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5994                    mCoreSettingsObserver.getCoreSettingsLocked());
5995            updateLruProcessLocked(app, false, null);
5996            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5997        } catch (Exception e) {
5998            // todo: Yikes!  What should we do?  For now we will try to
5999            // start another process, but that could easily get us in
6000            // an infinite loop of restarting processes...
6001            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6002
6003            app.resetPackageList(mProcessStats);
6004            app.unlinkDeathRecipient();
6005            startProcessLocked(app, "bind fail", processName);
6006            return false;
6007        }
6008
6009        // Remove this record from the list of starting applications.
6010        mPersistentStartingProcesses.remove(app);
6011        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6012                "Attach application locked removing on hold: " + app);
6013        mProcessesOnHold.remove(app);
6014
6015        boolean badApp = false;
6016        boolean didSomething = false;
6017
6018        // See if the top visible activity is waiting to run in this process...
6019        if (normalMode) {
6020            try {
6021                if (mStackSupervisor.attachApplicationLocked(app)) {
6022                    didSomething = true;
6023                }
6024            } catch (Exception e) {
6025                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6026                badApp = true;
6027            }
6028        }
6029
6030        // Find any services that should be running in this process...
6031        if (!badApp) {
6032            try {
6033                didSomething |= mServices.attachApplicationLocked(app, processName);
6034            } catch (Exception e) {
6035                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6036                badApp = true;
6037            }
6038        }
6039
6040        // Check if a next-broadcast receiver is in this process...
6041        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6042            try {
6043                didSomething |= sendPendingBroadcastsLocked(app);
6044            } catch (Exception e) {
6045                // If the app died trying to launch the receiver we declare it 'bad'
6046                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6047                badApp = true;
6048            }
6049        }
6050
6051        // Check whether the next backup agent is in this process...
6052        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6053            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6054            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6055            try {
6056                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6057                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6058                        mBackupTarget.backupMode);
6059            } catch (Exception e) {
6060                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6061                badApp = true;
6062            }
6063        }
6064
6065        if (badApp) {
6066            app.kill("error during init", true);
6067            handleAppDiedLocked(app, false, true);
6068            return false;
6069        }
6070
6071        if (!didSomething) {
6072            updateOomAdjLocked();
6073        }
6074
6075        return true;
6076    }
6077
6078    @Override
6079    public final void attachApplication(IApplicationThread thread) {
6080        synchronized (this) {
6081            int callingPid = Binder.getCallingPid();
6082            final long origId = Binder.clearCallingIdentity();
6083            attachApplicationLocked(thread, callingPid);
6084            Binder.restoreCallingIdentity(origId);
6085        }
6086    }
6087
6088    @Override
6089    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6090        final long origId = Binder.clearCallingIdentity();
6091        synchronized (this) {
6092            ActivityStack stack = ActivityRecord.getStackLocked(token);
6093            if (stack != null) {
6094                ActivityRecord r =
6095                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6096                if (stopProfiling) {
6097                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6098                        try {
6099                            mProfileFd.close();
6100                        } catch (IOException e) {
6101                        }
6102                        clearProfilerLocked();
6103                    }
6104                }
6105            }
6106        }
6107        Binder.restoreCallingIdentity(origId);
6108    }
6109
6110    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6111        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6112                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6113    }
6114
6115    void enableScreenAfterBoot() {
6116        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6117                SystemClock.uptimeMillis());
6118        mWindowManager.enableScreenAfterBoot();
6119
6120        synchronized (this) {
6121            updateEventDispatchingLocked();
6122        }
6123    }
6124
6125    @Override
6126    public void showBootMessage(final CharSequence msg, final boolean always) {
6127        enforceNotIsolatedCaller("showBootMessage");
6128        mWindowManager.showBootMessage(msg, always);
6129    }
6130
6131    @Override
6132    public void keyguardWaitingForActivityDrawn() {
6133        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6134        final long token = Binder.clearCallingIdentity();
6135        try {
6136            synchronized (this) {
6137                if (DEBUG_LOCKSCREEN) logLockScreen("");
6138                mWindowManager.keyguardWaitingForActivityDrawn();
6139                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6140                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6141                }
6142            }
6143        } finally {
6144            Binder.restoreCallingIdentity(token);
6145        }
6146    }
6147
6148    final void finishBooting() {
6149        synchronized (this) {
6150            if (!mBootAnimationComplete) {
6151                mCallFinishBooting = true;
6152                return;
6153            }
6154            mCallFinishBooting = false;
6155        }
6156
6157        ArraySet<String> completedIsas = new ArraySet<String>();
6158        for (String abi : Build.SUPPORTED_ABIS) {
6159            Process.establishZygoteConnectionForAbi(abi);
6160            final String instructionSet = VMRuntime.getInstructionSet(abi);
6161            if (!completedIsas.contains(instructionSet)) {
6162                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6163                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6164                }
6165                completedIsas.add(instructionSet);
6166            }
6167        }
6168
6169        // Register receivers to handle package update events
6170        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6171
6172        // Let system services know.
6173        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6174
6175        synchronized (this) {
6176            // Ensure that any processes we had put on hold are now started
6177            // up.
6178            final int NP = mProcessesOnHold.size();
6179            if (NP > 0) {
6180                ArrayList<ProcessRecord> procs =
6181                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6182                for (int ip=0; ip<NP; ip++) {
6183                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6184                            + procs.get(ip));
6185                    startProcessLocked(procs.get(ip), "on-hold", null);
6186                }
6187            }
6188
6189            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6190                // Start looking for apps that are abusing wake locks.
6191                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6192                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6193                // Tell anyone interested that we are done booting!
6194                SystemProperties.set("sys.boot_completed", "1");
6195
6196                // And trigger dev.bootcomplete if we are not showing encryption progress
6197                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6198                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6199                    SystemProperties.set("dev.bootcomplete", "1");
6200                }
6201                for (int i=0; i<mStartedUsers.size(); i++) {
6202                    UserStartedState uss = mStartedUsers.valueAt(i);
6203                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6204                        uss.mState = UserStartedState.STATE_RUNNING;
6205                        final int userId = mStartedUsers.keyAt(i);
6206                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6207                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6208                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6209                        broadcastIntentLocked(null, null, intent, null,
6210                                new IIntentReceiver.Stub() {
6211                                    @Override
6212                                    public void performReceive(Intent intent, int resultCode,
6213                                            String data, Bundle extras, boolean ordered,
6214                                            boolean sticky, int sendingUser) {
6215                                        synchronized (ActivityManagerService.this) {
6216                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6217                                                    true, false);
6218                                        }
6219                                    }
6220                                },
6221                                0, null, null,
6222                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6223                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6224                                userId);
6225                    }
6226                }
6227                scheduleStartProfilesLocked();
6228            }
6229        }
6230    }
6231
6232    @Override
6233    public void bootAnimationComplete() {
6234        final boolean callFinishBooting;
6235        synchronized (this) {
6236            callFinishBooting = mCallFinishBooting;
6237            mBootAnimationComplete = true;
6238        }
6239        if (callFinishBooting) {
6240            finishBooting();
6241        }
6242    }
6243
6244    final void ensureBootCompleted() {
6245        boolean booting;
6246        boolean enableScreen;
6247        synchronized (this) {
6248            booting = mBooting;
6249            mBooting = false;
6250            enableScreen = !mBooted;
6251            mBooted = true;
6252        }
6253
6254        if (booting) {
6255            finishBooting();
6256        }
6257
6258        if (enableScreen) {
6259            enableScreenAfterBoot();
6260        }
6261    }
6262
6263    @Override
6264    public final void activityResumed(IBinder token) {
6265        final long origId = Binder.clearCallingIdentity();
6266        synchronized(this) {
6267            ActivityStack stack = ActivityRecord.getStackLocked(token);
6268            if (stack != null) {
6269                ActivityRecord.activityResumedLocked(token);
6270            }
6271        }
6272        Binder.restoreCallingIdentity(origId);
6273    }
6274
6275    @Override
6276    public final void activityPaused(IBinder token) {
6277        final long origId = Binder.clearCallingIdentity();
6278        synchronized(this) {
6279            ActivityStack stack = ActivityRecord.getStackLocked(token);
6280            if (stack != null) {
6281                stack.activityPausedLocked(token, false);
6282            }
6283        }
6284        Binder.restoreCallingIdentity(origId);
6285    }
6286
6287    @Override
6288    public final void activityStopped(IBinder token, Bundle icicle,
6289            PersistableBundle persistentState, CharSequence description) {
6290        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6291
6292        // Refuse possible leaked file descriptors
6293        if (icicle != null && icicle.hasFileDescriptors()) {
6294            throw new IllegalArgumentException("File descriptors passed in Bundle");
6295        }
6296
6297        final long origId = Binder.clearCallingIdentity();
6298
6299        synchronized (this) {
6300            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6301            if (r != null) {
6302                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6303            }
6304        }
6305
6306        trimApplications();
6307
6308        Binder.restoreCallingIdentity(origId);
6309    }
6310
6311    @Override
6312    public final void activityDestroyed(IBinder token) {
6313        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6314        synchronized (this) {
6315            ActivityStack stack = ActivityRecord.getStackLocked(token);
6316            if (stack != null) {
6317                stack.activityDestroyedLocked(token);
6318            }
6319        }
6320    }
6321
6322    @Override
6323    public final void backgroundResourcesReleased(IBinder token) {
6324        final long origId = Binder.clearCallingIdentity();
6325        try {
6326            synchronized (this) {
6327                ActivityStack stack = ActivityRecord.getStackLocked(token);
6328                if (stack != null) {
6329                    stack.backgroundResourcesReleased(token);
6330                }
6331            }
6332        } finally {
6333            Binder.restoreCallingIdentity(origId);
6334        }
6335    }
6336
6337    @Override
6338    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6339        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6340    }
6341
6342    @Override
6343    public final void notifyEnterAnimationComplete(IBinder token) {
6344        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6345    }
6346
6347    @Override
6348    public String getCallingPackage(IBinder token) {
6349        synchronized (this) {
6350            ActivityRecord r = getCallingRecordLocked(token);
6351            return r != null ? r.info.packageName : null;
6352        }
6353    }
6354
6355    @Override
6356    public ComponentName getCallingActivity(IBinder token) {
6357        synchronized (this) {
6358            ActivityRecord r = getCallingRecordLocked(token);
6359            return r != null ? r.intent.getComponent() : null;
6360        }
6361    }
6362
6363    private ActivityRecord getCallingRecordLocked(IBinder token) {
6364        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6365        if (r == null) {
6366            return null;
6367        }
6368        return r.resultTo;
6369    }
6370
6371    @Override
6372    public ComponentName getActivityClassForToken(IBinder token) {
6373        synchronized(this) {
6374            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6375            if (r == null) {
6376                return null;
6377            }
6378            return r.intent.getComponent();
6379        }
6380    }
6381
6382    @Override
6383    public String getPackageForToken(IBinder token) {
6384        synchronized(this) {
6385            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6386            if (r == null) {
6387                return null;
6388            }
6389            return r.packageName;
6390        }
6391    }
6392
6393    @Override
6394    public IIntentSender getIntentSender(int type,
6395            String packageName, IBinder token, String resultWho,
6396            int requestCode, Intent[] intents, String[] resolvedTypes,
6397            int flags, Bundle options, int userId) {
6398        enforceNotIsolatedCaller("getIntentSender");
6399        // Refuse possible leaked file descriptors
6400        if (intents != null) {
6401            if (intents.length < 1) {
6402                throw new IllegalArgumentException("Intents array length must be >= 1");
6403            }
6404            for (int i=0; i<intents.length; i++) {
6405                Intent intent = intents[i];
6406                if (intent != null) {
6407                    if (intent.hasFileDescriptors()) {
6408                        throw new IllegalArgumentException("File descriptors passed in Intent");
6409                    }
6410                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6411                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6412                        throw new IllegalArgumentException(
6413                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6414                    }
6415                    intents[i] = new Intent(intent);
6416                }
6417            }
6418            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6419                throw new IllegalArgumentException(
6420                        "Intent array length does not match resolvedTypes length");
6421            }
6422        }
6423        if (options != null) {
6424            if (options.hasFileDescriptors()) {
6425                throw new IllegalArgumentException("File descriptors passed in options");
6426            }
6427        }
6428
6429        synchronized(this) {
6430            int callingUid = Binder.getCallingUid();
6431            int origUserId = userId;
6432            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6433                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6434                    ALLOW_NON_FULL, "getIntentSender", null);
6435            if (origUserId == UserHandle.USER_CURRENT) {
6436                // We don't want to evaluate this until the pending intent is
6437                // actually executed.  However, we do want to always do the
6438                // security checking for it above.
6439                userId = UserHandle.USER_CURRENT;
6440            }
6441            try {
6442                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6443                    int uid = AppGlobals.getPackageManager()
6444                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6445                    if (!UserHandle.isSameApp(callingUid, uid)) {
6446                        String msg = "Permission Denial: getIntentSender() from pid="
6447                            + Binder.getCallingPid()
6448                            + ", uid=" + Binder.getCallingUid()
6449                            + ", (need uid=" + uid + ")"
6450                            + " is not allowed to send as package " + packageName;
6451                        Slog.w(TAG, msg);
6452                        throw new SecurityException(msg);
6453                    }
6454                }
6455
6456                return getIntentSenderLocked(type, packageName, callingUid, userId,
6457                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6458
6459            } catch (RemoteException e) {
6460                throw new SecurityException(e);
6461            }
6462        }
6463    }
6464
6465    IIntentSender getIntentSenderLocked(int type, String packageName,
6466            int callingUid, int userId, IBinder token, String resultWho,
6467            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6468            Bundle options) {
6469        if (DEBUG_MU)
6470            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6471        ActivityRecord activity = null;
6472        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6473            activity = ActivityRecord.isInStackLocked(token);
6474            if (activity == null) {
6475                return null;
6476            }
6477            if (activity.finishing) {
6478                return null;
6479            }
6480        }
6481
6482        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6483        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6484        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6485        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6486                |PendingIntent.FLAG_UPDATE_CURRENT);
6487
6488        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6489                type, packageName, activity, resultWho,
6490                requestCode, intents, resolvedTypes, flags, options, userId);
6491        WeakReference<PendingIntentRecord> ref;
6492        ref = mIntentSenderRecords.get(key);
6493        PendingIntentRecord rec = ref != null ? ref.get() : null;
6494        if (rec != null) {
6495            if (!cancelCurrent) {
6496                if (updateCurrent) {
6497                    if (rec.key.requestIntent != null) {
6498                        rec.key.requestIntent.replaceExtras(intents != null ?
6499                                intents[intents.length - 1] : null);
6500                    }
6501                    if (intents != null) {
6502                        intents[intents.length-1] = rec.key.requestIntent;
6503                        rec.key.allIntents = intents;
6504                        rec.key.allResolvedTypes = resolvedTypes;
6505                    } else {
6506                        rec.key.allIntents = null;
6507                        rec.key.allResolvedTypes = null;
6508                    }
6509                }
6510                return rec;
6511            }
6512            rec.canceled = true;
6513            mIntentSenderRecords.remove(key);
6514        }
6515        if (noCreate) {
6516            return rec;
6517        }
6518        rec = new PendingIntentRecord(this, key, callingUid);
6519        mIntentSenderRecords.put(key, rec.ref);
6520        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6521            if (activity.pendingResults == null) {
6522                activity.pendingResults
6523                        = new HashSet<WeakReference<PendingIntentRecord>>();
6524            }
6525            activity.pendingResults.add(rec.ref);
6526        }
6527        return rec;
6528    }
6529
6530    @Override
6531    public void cancelIntentSender(IIntentSender sender) {
6532        if (!(sender instanceof PendingIntentRecord)) {
6533            return;
6534        }
6535        synchronized(this) {
6536            PendingIntentRecord rec = (PendingIntentRecord)sender;
6537            try {
6538                int uid = AppGlobals.getPackageManager()
6539                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6540                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6541                    String msg = "Permission Denial: cancelIntentSender() from pid="
6542                        + Binder.getCallingPid()
6543                        + ", uid=" + Binder.getCallingUid()
6544                        + " is not allowed to cancel packges "
6545                        + rec.key.packageName;
6546                    Slog.w(TAG, msg);
6547                    throw new SecurityException(msg);
6548                }
6549            } catch (RemoteException e) {
6550                throw new SecurityException(e);
6551            }
6552            cancelIntentSenderLocked(rec, true);
6553        }
6554    }
6555
6556    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6557        rec.canceled = true;
6558        mIntentSenderRecords.remove(rec.key);
6559        if (cleanActivity && rec.key.activity != null) {
6560            rec.key.activity.pendingResults.remove(rec.ref);
6561        }
6562    }
6563
6564    @Override
6565    public String getPackageForIntentSender(IIntentSender pendingResult) {
6566        if (!(pendingResult instanceof PendingIntentRecord)) {
6567            return null;
6568        }
6569        try {
6570            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6571            return res.key.packageName;
6572        } catch (ClassCastException e) {
6573        }
6574        return null;
6575    }
6576
6577    @Override
6578    public int getUidForIntentSender(IIntentSender sender) {
6579        if (sender instanceof PendingIntentRecord) {
6580            try {
6581                PendingIntentRecord res = (PendingIntentRecord)sender;
6582                return res.uid;
6583            } catch (ClassCastException e) {
6584            }
6585        }
6586        return -1;
6587    }
6588
6589    @Override
6590    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6591        if (!(pendingResult instanceof PendingIntentRecord)) {
6592            return false;
6593        }
6594        try {
6595            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6596            if (res.key.allIntents == null) {
6597                return false;
6598            }
6599            for (int i=0; i<res.key.allIntents.length; i++) {
6600                Intent intent = res.key.allIntents[i];
6601                if (intent.getPackage() != null && intent.getComponent() != null) {
6602                    return false;
6603                }
6604            }
6605            return true;
6606        } catch (ClassCastException e) {
6607        }
6608        return false;
6609    }
6610
6611    @Override
6612    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6613        if (!(pendingResult instanceof PendingIntentRecord)) {
6614            return false;
6615        }
6616        try {
6617            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6618            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6619                return true;
6620            }
6621            return false;
6622        } catch (ClassCastException e) {
6623        }
6624        return false;
6625    }
6626
6627    @Override
6628    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6629        if (!(pendingResult instanceof PendingIntentRecord)) {
6630            return null;
6631        }
6632        try {
6633            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6634            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6635        } catch (ClassCastException e) {
6636        }
6637        return null;
6638    }
6639
6640    @Override
6641    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6642        if (!(pendingResult instanceof PendingIntentRecord)) {
6643            return null;
6644        }
6645        try {
6646            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6647            Intent intent = res.key.requestIntent;
6648            if (intent != null) {
6649                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6650                        || res.lastTagPrefix.equals(prefix))) {
6651                    return res.lastTag;
6652                }
6653                res.lastTagPrefix = prefix;
6654                StringBuilder sb = new StringBuilder(128);
6655                if (prefix != null) {
6656                    sb.append(prefix);
6657                }
6658                if (intent.getAction() != null) {
6659                    sb.append(intent.getAction());
6660                } else if (intent.getComponent() != null) {
6661                    intent.getComponent().appendShortString(sb);
6662                } else {
6663                    sb.append("?");
6664                }
6665                return res.lastTag = sb.toString();
6666            }
6667        } catch (ClassCastException e) {
6668        }
6669        return null;
6670    }
6671
6672    @Override
6673    public void setProcessLimit(int max) {
6674        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6675                "setProcessLimit()");
6676        synchronized (this) {
6677            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6678            mProcessLimitOverride = max;
6679        }
6680        trimApplications();
6681    }
6682
6683    @Override
6684    public int getProcessLimit() {
6685        synchronized (this) {
6686            return mProcessLimitOverride;
6687        }
6688    }
6689
6690    void foregroundTokenDied(ForegroundToken token) {
6691        synchronized (ActivityManagerService.this) {
6692            synchronized (mPidsSelfLocked) {
6693                ForegroundToken cur
6694                    = mForegroundProcesses.get(token.pid);
6695                if (cur != token) {
6696                    return;
6697                }
6698                mForegroundProcesses.remove(token.pid);
6699                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6700                if (pr == null) {
6701                    return;
6702                }
6703                pr.forcingToForeground = null;
6704                updateProcessForegroundLocked(pr, false, false);
6705            }
6706            updateOomAdjLocked();
6707        }
6708    }
6709
6710    @Override
6711    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6712        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6713                "setProcessForeground()");
6714        synchronized(this) {
6715            boolean changed = false;
6716
6717            synchronized (mPidsSelfLocked) {
6718                ProcessRecord pr = mPidsSelfLocked.get(pid);
6719                if (pr == null && isForeground) {
6720                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6721                    return;
6722                }
6723                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6724                if (oldToken != null) {
6725                    oldToken.token.unlinkToDeath(oldToken, 0);
6726                    mForegroundProcesses.remove(pid);
6727                    if (pr != null) {
6728                        pr.forcingToForeground = null;
6729                    }
6730                    changed = true;
6731                }
6732                if (isForeground && token != null) {
6733                    ForegroundToken newToken = new ForegroundToken() {
6734                        @Override
6735                        public void binderDied() {
6736                            foregroundTokenDied(this);
6737                        }
6738                    };
6739                    newToken.pid = pid;
6740                    newToken.token = token;
6741                    try {
6742                        token.linkToDeath(newToken, 0);
6743                        mForegroundProcesses.put(pid, newToken);
6744                        pr.forcingToForeground = token;
6745                        changed = true;
6746                    } catch (RemoteException e) {
6747                        // If the process died while doing this, we will later
6748                        // do the cleanup with the process death link.
6749                    }
6750                }
6751            }
6752
6753            if (changed) {
6754                updateOomAdjLocked();
6755            }
6756        }
6757    }
6758
6759    // =========================================================
6760    // PERMISSIONS
6761    // =========================================================
6762
6763    static class PermissionController extends IPermissionController.Stub {
6764        ActivityManagerService mActivityManagerService;
6765        PermissionController(ActivityManagerService activityManagerService) {
6766            mActivityManagerService = activityManagerService;
6767        }
6768
6769        @Override
6770        public boolean checkPermission(String permission, int pid, int uid) {
6771            return mActivityManagerService.checkPermission(permission, pid,
6772                    uid) == PackageManager.PERMISSION_GRANTED;
6773        }
6774    }
6775
6776    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6777        @Override
6778        public int checkComponentPermission(String permission, int pid, int uid,
6779                int owningUid, boolean exported) {
6780            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6781                    owningUid, exported);
6782        }
6783
6784        @Override
6785        public Object getAMSLock() {
6786            return ActivityManagerService.this;
6787        }
6788    }
6789
6790    /**
6791     * This can be called with or without the global lock held.
6792     */
6793    int checkComponentPermission(String permission, int pid, int uid,
6794            int owningUid, boolean exported) {
6795        // We might be performing an operation on behalf of an indirect binder
6796        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6797        // client identity accordingly before proceeding.
6798        Identity tlsIdentity = sCallerIdentity.get();
6799        if (tlsIdentity != null) {
6800            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6801                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6802            uid = tlsIdentity.uid;
6803            pid = tlsIdentity.pid;
6804        }
6805
6806        if (pid == MY_PID) {
6807            return PackageManager.PERMISSION_GRANTED;
6808        }
6809
6810        return ActivityManager.checkComponentPermission(permission, uid,
6811                owningUid, exported);
6812    }
6813
6814    /**
6815     * As the only public entry point for permissions checking, this method
6816     * can enforce the semantic that requesting a check on a null global
6817     * permission is automatically denied.  (Internally a null permission
6818     * string is used when calling {@link #checkComponentPermission} in cases
6819     * when only uid-based security is needed.)
6820     *
6821     * This can be called with or without the global lock held.
6822     */
6823    @Override
6824    public int checkPermission(String permission, int pid, int uid) {
6825        if (permission == null) {
6826            return PackageManager.PERMISSION_DENIED;
6827        }
6828        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6829    }
6830
6831    /**
6832     * Binder IPC calls go through the public entry point.
6833     * This can be called with or without the global lock held.
6834     */
6835    int checkCallingPermission(String permission) {
6836        return checkPermission(permission,
6837                Binder.getCallingPid(),
6838                UserHandle.getAppId(Binder.getCallingUid()));
6839    }
6840
6841    /**
6842     * This can be called with or without the global lock held.
6843     */
6844    void enforceCallingPermission(String permission, String func) {
6845        if (checkCallingPermission(permission)
6846                == PackageManager.PERMISSION_GRANTED) {
6847            return;
6848        }
6849
6850        String msg = "Permission Denial: " + func + " from pid="
6851                + Binder.getCallingPid()
6852                + ", uid=" + Binder.getCallingUid()
6853                + " requires " + permission;
6854        Slog.w(TAG, msg);
6855        throw new SecurityException(msg);
6856    }
6857
6858    /**
6859     * Determine if UID is holding permissions required to access {@link Uri} in
6860     * the given {@link ProviderInfo}. Final permission checking is always done
6861     * in {@link ContentProvider}.
6862     */
6863    private final boolean checkHoldingPermissionsLocked(
6864            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6865        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6866                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6867        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6868            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6869                    != PERMISSION_GRANTED) {
6870                return false;
6871            }
6872        }
6873        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6874    }
6875
6876    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6877            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6878        if (pi.applicationInfo.uid == uid) {
6879            return true;
6880        } else if (!pi.exported) {
6881            return false;
6882        }
6883
6884        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6885        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6886        try {
6887            // check if target holds top-level <provider> permissions
6888            if (!readMet && pi.readPermission != null && considerUidPermissions
6889                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6890                readMet = true;
6891            }
6892            if (!writeMet && pi.writePermission != null && considerUidPermissions
6893                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6894                writeMet = true;
6895            }
6896
6897            // track if unprotected read/write is allowed; any denied
6898            // <path-permission> below removes this ability
6899            boolean allowDefaultRead = pi.readPermission == null;
6900            boolean allowDefaultWrite = pi.writePermission == null;
6901
6902            // check if target holds any <path-permission> that match uri
6903            final PathPermission[] pps = pi.pathPermissions;
6904            if (pps != null) {
6905                final String path = grantUri.uri.getPath();
6906                int i = pps.length;
6907                while (i > 0 && (!readMet || !writeMet)) {
6908                    i--;
6909                    PathPermission pp = pps[i];
6910                    if (pp.match(path)) {
6911                        if (!readMet) {
6912                            final String pprperm = pp.getReadPermission();
6913                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6914                                    + pprperm + " for " + pp.getPath()
6915                                    + ": match=" + pp.match(path)
6916                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6917                            if (pprperm != null) {
6918                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6919                                        == PERMISSION_GRANTED) {
6920                                    readMet = true;
6921                                } else {
6922                                    allowDefaultRead = false;
6923                                }
6924                            }
6925                        }
6926                        if (!writeMet) {
6927                            final String ppwperm = pp.getWritePermission();
6928                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6929                                    + ppwperm + " for " + pp.getPath()
6930                                    + ": match=" + pp.match(path)
6931                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6932                            if (ppwperm != null) {
6933                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6934                                        == PERMISSION_GRANTED) {
6935                                    writeMet = true;
6936                                } else {
6937                                    allowDefaultWrite = false;
6938                                }
6939                            }
6940                        }
6941                    }
6942                }
6943            }
6944
6945            // grant unprotected <provider> read/write, if not blocked by
6946            // <path-permission> above
6947            if (allowDefaultRead) readMet = true;
6948            if (allowDefaultWrite) writeMet = true;
6949
6950        } catch (RemoteException e) {
6951            return false;
6952        }
6953
6954        return readMet && writeMet;
6955    }
6956
6957    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6958        ProviderInfo pi = null;
6959        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6960        if (cpr != null) {
6961            pi = cpr.info;
6962        } else {
6963            try {
6964                pi = AppGlobals.getPackageManager().resolveContentProvider(
6965                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6966            } catch (RemoteException ex) {
6967            }
6968        }
6969        return pi;
6970    }
6971
6972    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6973        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6974        if (targetUris != null) {
6975            return targetUris.get(grantUri);
6976        }
6977        return null;
6978    }
6979
6980    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6981            String targetPkg, int targetUid, GrantUri grantUri) {
6982        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6983        if (targetUris == null) {
6984            targetUris = Maps.newArrayMap();
6985            mGrantedUriPermissions.put(targetUid, targetUris);
6986        }
6987
6988        UriPermission perm = targetUris.get(grantUri);
6989        if (perm == null) {
6990            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6991            targetUris.put(grantUri, perm);
6992        }
6993
6994        return perm;
6995    }
6996
6997    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6998            final int modeFlags) {
6999        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7000        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7001                : UriPermission.STRENGTH_OWNED;
7002
7003        // Root gets to do everything.
7004        if (uid == 0) {
7005            return true;
7006        }
7007
7008        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7009        if (perms == null) return false;
7010
7011        // First look for exact match
7012        final UriPermission exactPerm = perms.get(grantUri);
7013        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7014            return true;
7015        }
7016
7017        // No exact match, look for prefixes
7018        final int N = perms.size();
7019        for (int i = 0; i < N; i++) {
7020            final UriPermission perm = perms.valueAt(i);
7021            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7022                    && perm.getStrength(modeFlags) >= minStrength) {
7023                return true;
7024            }
7025        }
7026
7027        return false;
7028    }
7029
7030    /**
7031     * @param uri This uri must NOT contain an embedded userId.
7032     * @param userId The userId in which the uri is to be resolved.
7033     */
7034    @Override
7035    public int checkUriPermission(Uri uri, int pid, int uid,
7036            final int modeFlags, int userId) {
7037        enforceNotIsolatedCaller("checkUriPermission");
7038
7039        // Another redirected-binder-call permissions check as in
7040        // {@link checkComponentPermission}.
7041        Identity tlsIdentity = sCallerIdentity.get();
7042        if (tlsIdentity != null) {
7043            uid = tlsIdentity.uid;
7044            pid = tlsIdentity.pid;
7045        }
7046
7047        // Our own process gets to do everything.
7048        if (pid == MY_PID) {
7049            return PackageManager.PERMISSION_GRANTED;
7050        }
7051        synchronized (this) {
7052            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7053                    ? PackageManager.PERMISSION_GRANTED
7054                    : PackageManager.PERMISSION_DENIED;
7055        }
7056    }
7057
7058    /**
7059     * Check if the targetPkg can be granted permission to access uri by
7060     * the callingUid using the given modeFlags.  Throws a security exception
7061     * if callingUid is not allowed to do this.  Returns the uid of the target
7062     * if the URI permission grant should be performed; returns -1 if it is not
7063     * needed (for example targetPkg already has permission to access the URI).
7064     * If you already know the uid of the target, you can supply it in
7065     * lastTargetUid else set that to -1.
7066     */
7067    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7068            final int modeFlags, int lastTargetUid) {
7069        if (!Intent.isAccessUriMode(modeFlags)) {
7070            return -1;
7071        }
7072
7073        if (targetPkg != null) {
7074            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7075                    "Checking grant " + targetPkg + " permission to " + grantUri);
7076        }
7077
7078        final IPackageManager pm = AppGlobals.getPackageManager();
7079
7080        // If this is not a content: uri, we can't do anything with it.
7081        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7082            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7083                    "Can't grant URI permission for non-content URI: " + grantUri);
7084            return -1;
7085        }
7086
7087        final String authority = grantUri.uri.getAuthority();
7088        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7089        if (pi == null) {
7090            Slog.w(TAG, "No content provider found for permission check: " +
7091                    grantUri.uri.toSafeString());
7092            return -1;
7093        }
7094
7095        int targetUid = lastTargetUid;
7096        if (targetUid < 0 && targetPkg != null) {
7097            try {
7098                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7099                if (targetUid < 0) {
7100                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7101                            "Can't grant URI permission no uid for: " + targetPkg);
7102                    return -1;
7103                }
7104            } catch (RemoteException ex) {
7105                return -1;
7106            }
7107        }
7108
7109        if (targetUid >= 0) {
7110            // First...  does the target actually need this permission?
7111            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7112                // No need to grant the target this permission.
7113                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7114                        "Target " + targetPkg + " already has full permission to " + grantUri);
7115                return -1;
7116            }
7117        } else {
7118            // First...  there is no target package, so can anyone access it?
7119            boolean allowed = pi.exported;
7120            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7121                if (pi.readPermission != null) {
7122                    allowed = false;
7123                }
7124            }
7125            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7126                if (pi.writePermission != null) {
7127                    allowed = false;
7128                }
7129            }
7130            if (allowed) {
7131                return -1;
7132            }
7133        }
7134
7135        /* There is a special cross user grant if:
7136         * - The target is on another user.
7137         * - Apps on the current user can access the uri without any uid permissions.
7138         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7139         * grant uri permissions.
7140         */
7141        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7142                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7143                modeFlags, false /*without considering the uid permissions*/);
7144
7145        // Second...  is the provider allowing granting of URI permissions?
7146        if (!specialCrossUserGrant) {
7147            if (!pi.grantUriPermissions) {
7148                throw new SecurityException("Provider " + pi.packageName
7149                        + "/" + pi.name
7150                        + " does not allow granting of Uri permissions (uri "
7151                        + grantUri + ")");
7152            }
7153            if (pi.uriPermissionPatterns != null) {
7154                final int N = pi.uriPermissionPatterns.length;
7155                boolean allowed = false;
7156                for (int i=0; i<N; i++) {
7157                    if (pi.uriPermissionPatterns[i] != null
7158                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7159                        allowed = true;
7160                        break;
7161                    }
7162                }
7163                if (!allowed) {
7164                    throw new SecurityException("Provider " + pi.packageName
7165                            + "/" + pi.name
7166                            + " does not allow granting of permission to path of Uri "
7167                            + grantUri);
7168                }
7169            }
7170        }
7171
7172        // Third...  does the caller itself have permission to access
7173        // this uri?
7174        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7175            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7176                // Require they hold a strong enough Uri permission
7177                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7178                    throw new SecurityException("Uid " + callingUid
7179                            + " does not have permission to uri " + grantUri);
7180                }
7181            }
7182        }
7183        return targetUid;
7184    }
7185
7186    /**
7187     * @param uri This uri must NOT contain an embedded userId.
7188     * @param userId The userId in which the uri is to be resolved.
7189     */
7190    @Override
7191    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7192            final int modeFlags, int userId) {
7193        enforceNotIsolatedCaller("checkGrantUriPermission");
7194        synchronized(this) {
7195            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7196                    new GrantUri(userId, uri, false), modeFlags, -1);
7197        }
7198    }
7199
7200    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7201            final int modeFlags, UriPermissionOwner owner) {
7202        if (!Intent.isAccessUriMode(modeFlags)) {
7203            return;
7204        }
7205
7206        // So here we are: the caller has the assumed permission
7207        // to the uri, and the target doesn't.  Let's now give this to
7208        // the target.
7209
7210        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7211                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7212
7213        final String authority = grantUri.uri.getAuthority();
7214        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7215        if (pi == null) {
7216            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7217            return;
7218        }
7219
7220        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7221            grantUri.prefix = true;
7222        }
7223        final UriPermission perm = findOrCreateUriPermissionLocked(
7224                pi.packageName, targetPkg, targetUid, grantUri);
7225        perm.grantModes(modeFlags, owner);
7226    }
7227
7228    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7229            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7230        if (targetPkg == null) {
7231            throw new NullPointerException("targetPkg");
7232        }
7233        int targetUid;
7234        final IPackageManager pm = AppGlobals.getPackageManager();
7235        try {
7236            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7237        } catch (RemoteException ex) {
7238            return;
7239        }
7240
7241        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7242                targetUid);
7243        if (targetUid < 0) {
7244            return;
7245        }
7246
7247        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7248                owner);
7249    }
7250
7251    static class NeededUriGrants extends ArrayList<GrantUri> {
7252        final String targetPkg;
7253        final int targetUid;
7254        final int flags;
7255
7256        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7257            this.targetPkg = targetPkg;
7258            this.targetUid = targetUid;
7259            this.flags = flags;
7260        }
7261    }
7262
7263    /**
7264     * Like checkGrantUriPermissionLocked, but takes an Intent.
7265     */
7266    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7267            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7268        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7269                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7270                + " clip=" + (intent != null ? intent.getClipData() : null)
7271                + " from " + intent + "; flags=0x"
7272                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7273
7274        if (targetPkg == null) {
7275            throw new NullPointerException("targetPkg");
7276        }
7277
7278        if (intent == null) {
7279            return null;
7280        }
7281        Uri data = intent.getData();
7282        ClipData clip = intent.getClipData();
7283        if (data == null && clip == null) {
7284            return null;
7285        }
7286        // Default userId for uris in the intent (if they don't specify it themselves)
7287        int contentUserHint = intent.getContentUserHint();
7288        if (contentUserHint == UserHandle.USER_CURRENT) {
7289            contentUserHint = UserHandle.getUserId(callingUid);
7290        }
7291        final IPackageManager pm = AppGlobals.getPackageManager();
7292        int targetUid;
7293        if (needed != null) {
7294            targetUid = needed.targetUid;
7295        } else {
7296            try {
7297                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7298            } catch (RemoteException ex) {
7299                return null;
7300            }
7301            if (targetUid < 0) {
7302                if (DEBUG_URI_PERMISSION) {
7303                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7304                            + " on user " + targetUserId);
7305                }
7306                return null;
7307            }
7308        }
7309        if (data != null) {
7310            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7311            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7312                    targetUid);
7313            if (targetUid > 0) {
7314                if (needed == null) {
7315                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7316                }
7317                needed.add(grantUri);
7318            }
7319        }
7320        if (clip != null) {
7321            for (int i=0; i<clip.getItemCount(); i++) {
7322                Uri uri = clip.getItemAt(i).getUri();
7323                if (uri != null) {
7324                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7325                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7326                            targetUid);
7327                    if (targetUid > 0) {
7328                        if (needed == null) {
7329                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7330                        }
7331                        needed.add(grantUri);
7332                    }
7333                } else {
7334                    Intent clipIntent = clip.getItemAt(i).getIntent();
7335                    if (clipIntent != null) {
7336                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7337                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7338                        if (newNeeded != null) {
7339                            needed = newNeeded;
7340                        }
7341                    }
7342                }
7343            }
7344        }
7345
7346        return needed;
7347    }
7348
7349    /**
7350     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7351     */
7352    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7353            UriPermissionOwner owner) {
7354        if (needed != null) {
7355            for (int i=0; i<needed.size(); i++) {
7356                GrantUri grantUri = needed.get(i);
7357                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7358                        grantUri, needed.flags, owner);
7359            }
7360        }
7361    }
7362
7363    void grantUriPermissionFromIntentLocked(int callingUid,
7364            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7365        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7366                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7367        if (needed == null) {
7368            return;
7369        }
7370
7371        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7372    }
7373
7374    /**
7375     * @param uri This uri must NOT contain an embedded userId.
7376     * @param userId The userId in which the uri is to be resolved.
7377     */
7378    @Override
7379    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7380            final int modeFlags, int userId) {
7381        enforceNotIsolatedCaller("grantUriPermission");
7382        GrantUri grantUri = new GrantUri(userId, uri, false);
7383        synchronized(this) {
7384            final ProcessRecord r = getRecordForAppLocked(caller);
7385            if (r == null) {
7386                throw new SecurityException("Unable to find app for caller "
7387                        + caller
7388                        + " when granting permission to uri " + grantUri);
7389            }
7390            if (targetPkg == null) {
7391                throw new IllegalArgumentException("null target");
7392            }
7393            if (grantUri == null) {
7394                throw new IllegalArgumentException("null uri");
7395            }
7396
7397            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7398                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7399                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7400                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7401
7402            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7403                    UserHandle.getUserId(r.uid));
7404        }
7405    }
7406
7407    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7408        if (perm.modeFlags == 0) {
7409            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7410                    perm.targetUid);
7411            if (perms != null) {
7412                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7413                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7414
7415                perms.remove(perm.uri);
7416                if (perms.isEmpty()) {
7417                    mGrantedUriPermissions.remove(perm.targetUid);
7418                }
7419            }
7420        }
7421    }
7422
7423    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7424        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7425
7426        final IPackageManager pm = AppGlobals.getPackageManager();
7427        final String authority = grantUri.uri.getAuthority();
7428        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7429        if (pi == null) {
7430            Slog.w(TAG, "No content provider found for permission revoke: "
7431                    + grantUri.toSafeString());
7432            return;
7433        }
7434
7435        // Does the caller have this permission on the URI?
7436        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7437            // If they don't have direct access to the URI, then revoke any
7438            // ownerless URI permissions that have been granted to them.
7439            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7440            if (perms != null) {
7441                boolean persistChanged = false;
7442                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7443                    final UriPermission perm = it.next();
7444                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7445                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7446                        if (DEBUG_URI_PERMISSION)
7447                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7448                                    " permission to " + perm.uri);
7449                        persistChanged |= perm.revokeModes(
7450                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7451                        if (perm.modeFlags == 0) {
7452                            it.remove();
7453                        }
7454                    }
7455                }
7456                if (perms.isEmpty()) {
7457                    mGrantedUriPermissions.remove(callingUid);
7458                }
7459                if (persistChanged) {
7460                    schedulePersistUriGrants();
7461                }
7462            }
7463            return;
7464        }
7465
7466        boolean persistChanged = false;
7467
7468        // Go through all of the permissions and remove any that match.
7469        int N = mGrantedUriPermissions.size();
7470        for (int i = 0; i < N; i++) {
7471            final int targetUid = mGrantedUriPermissions.keyAt(i);
7472            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7473
7474            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7475                final UriPermission perm = it.next();
7476                if (perm.uri.sourceUserId == grantUri.sourceUserId
7477                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7478                    if (DEBUG_URI_PERMISSION)
7479                        Slog.v(TAG,
7480                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7481                    persistChanged |= perm.revokeModes(
7482                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7483                    if (perm.modeFlags == 0) {
7484                        it.remove();
7485                    }
7486                }
7487            }
7488
7489            if (perms.isEmpty()) {
7490                mGrantedUriPermissions.remove(targetUid);
7491                N--;
7492                i--;
7493            }
7494        }
7495
7496        if (persistChanged) {
7497            schedulePersistUriGrants();
7498        }
7499    }
7500
7501    /**
7502     * @param uri This uri must NOT contain an embedded userId.
7503     * @param userId The userId in which the uri is to be resolved.
7504     */
7505    @Override
7506    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7507            int userId) {
7508        enforceNotIsolatedCaller("revokeUriPermission");
7509        synchronized(this) {
7510            final ProcessRecord r = getRecordForAppLocked(caller);
7511            if (r == null) {
7512                throw new SecurityException("Unable to find app for caller "
7513                        + caller
7514                        + " when revoking permission to uri " + uri);
7515            }
7516            if (uri == null) {
7517                Slog.w(TAG, "revokeUriPermission: null uri");
7518                return;
7519            }
7520
7521            if (!Intent.isAccessUriMode(modeFlags)) {
7522                return;
7523            }
7524
7525            final IPackageManager pm = AppGlobals.getPackageManager();
7526            final String authority = uri.getAuthority();
7527            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7528            if (pi == null) {
7529                Slog.w(TAG, "No content provider found for permission revoke: "
7530                        + uri.toSafeString());
7531                return;
7532            }
7533
7534            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7535        }
7536    }
7537
7538    /**
7539     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7540     * given package.
7541     *
7542     * @param packageName Package name to match, or {@code null} to apply to all
7543     *            packages.
7544     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7545     *            to all users.
7546     * @param persistable If persistable grants should be removed.
7547     */
7548    private void removeUriPermissionsForPackageLocked(
7549            String packageName, int userHandle, boolean persistable) {
7550        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7551            throw new IllegalArgumentException("Must narrow by either package or user");
7552        }
7553
7554        boolean persistChanged = false;
7555
7556        int N = mGrantedUriPermissions.size();
7557        for (int i = 0; i < N; i++) {
7558            final int targetUid = mGrantedUriPermissions.keyAt(i);
7559            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7560
7561            // Only inspect grants matching user
7562            if (userHandle == UserHandle.USER_ALL
7563                    || userHandle == UserHandle.getUserId(targetUid)) {
7564                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7565                    final UriPermission perm = it.next();
7566
7567                    // Only inspect grants matching package
7568                    if (packageName == null || perm.sourcePkg.equals(packageName)
7569                            || perm.targetPkg.equals(packageName)) {
7570                        persistChanged |= perm.revokeModes(persistable
7571                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7572
7573                        // Only remove when no modes remain; any persisted grants
7574                        // will keep this alive.
7575                        if (perm.modeFlags == 0) {
7576                            it.remove();
7577                        }
7578                    }
7579                }
7580
7581                if (perms.isEmpty()) {
7582                    mGrantedUriPermissions.remove(targetUid);
7583                    N--;
7584                    i--;
7585                }
7586            }
7587        }
7588
7589        if (persistChanged) {
7590            schedulePersistUriGrants();
7591        }
7592    }
7593
7594    @Override
7595    public IBinder newUriPermissionOwner(String name) {
7596        enforceNotIsolatedCaller("newUriPermissionOwner");
7597        synchronized(this) {
7598            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7599            return owner.getExternalTokenLocked();
7600        }
7601    }
7602
7603    /**
7604     * @param uri This uri must NOT contain an embedded userId.
7605     * @param sourceUserId The userId in which the uri is to be resolved.
7606     * @param targetUserId The userId of the app that receives the grant.
7607     */
7608    @Override
7609    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7610            final int modeFlags, int sourceUserId, int targetUserId) {
7611        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7612                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7613        synchronized(this) {
7614            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7615            if (owner == null) {
7616                throw new IllegalArgumentException("Unknown owner: " + token);
7617            }
7618            if (fromUid != Binder.getCallingUid()) {
7619                if (Binder.getCallingUid() != Process.myUid()) {
7620                    // Only system code can grant URI permissions on behalf
7621                    // of other users.
7622                    throw new SecurityException("nice try");
7623                }
7624            }
7625            if (targetPkg == null) {
7626                throw new IllegalArgumentException("null target");
7627            }
7628            if (uri == null) {
7629                throw new IllegalArgumentException("null uri");
7630            }
7631
7632            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7633                    modeFlags, owner, targetUserId);
7634        }
7635    }
7636
7637    /**
7638     * @param uri This uri must NOT contain an embedded userId.
7639     * @param userId The userId in which the uri is to be resolved.
7640     */
7641    @Override
7642    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7643        synchronized(this) {
7644            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7645            if (owner == null) {
7646                throw new IllegalArgumentException("Unknown owner: " + token);
7647            }
7648
7649            if (uri == null) {
7650                owner.removeUriPermissionsLocked(mode);
7651            } else {
7652                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7653            }
7654        }
7655    }
7656
7657    private void schedulePersistUriGrants() {
7658        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7659            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7660                    10 * DateUtils.SECOND_IN_MILLIS);
7661        }
7662    }
7663
7664    private void writeGrantedUriPermissions() {
7665        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7666
7667        // Snapshot permissions so we can persist without lock
7668        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7669        synchronized (this) {
7670            final int size = mGrantedUriPermissions.size();
7671            for (int i = 0; i < size; i++) {
7672                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7673                for (UriPermission perm : perms.values()) {
7674                    if (perm.persistedModeFlags != 0) {
7675                        persist.add(perm.snapshot());
7676                    }
7677                }
7678            }
7679        }
7680
7681        FileOutputStream fos = null;
7682        try {
7683            fos = mGrantFile.startWrite();
7684
7685            XmlSerializer out = new FastXmlSerializer();
7686            out.setOutput(fos, "utf-8");
7687            out.startDocument(null, true);
7688            out.startTag(null, TAG_URI_GRANTS);
7689            for (UriPermission.Snapshot perm : persist) {
7690                out.startTag(null, TAG_URI_GRANT);
7691                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7692                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7693                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7694                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7695                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7696                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7697                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7698                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7699                out.endTag(null, TAG_URI_GRANT);
7700            }
7701            out.endTag(null, TAG_URI_GRANTS);
7702            out.endDocument();
7703
7704            mGrantFile.finishWrite(fos);
7705        } catch (IOException e) {
7706            if (fos != null) {
7707                mGrantFile.failWrite(fos);
7708            }
7709        }
7710    }
7711
7712    private void readGrantedUriPermissionsLocked() {
7713        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7714
7715        final long now = System.currentTimeMillis();
7716
7717        FileInputStream fis = null;
7718        try {
7719            fis = mGrantFile.openRead();
7720            final XmlPullParser in = Xml.newPullParser();
7721            in.setInput(fis, null);
7722
7723            int type;
7724            while ((type = in.next()) != END_DOCUMENT) {
7725                final String tag = in.getName();
7726                if (type == START_TAG) {
7727                    if (TAG_URI_GRANT.equals(tag)) {
7728                        final int sourceUserId;
7729                        final int targetUserId;
7730                        final int userHandle = readIntAttribute(in,
7731                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7732                        if (userHandle != UserHandle.USER_NULL) {
7733                            // For backwards compatibility.
7734                            sourceUserId = userHandle;
7735                            targetUserId = userHandle;
7736                        } else {
7737                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7738                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7739                        }
7740                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7741                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7742                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7743                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7744                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7745                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7746
7747                        // Sanity check that provider still belongs to source package
7748                        final ProviderInfo pi = getProviderInfoLocked(
7749                                uri.getAuthority(), sourceUserId);
7750                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7751                            int targetUid = -1;
7752                            try {
7753                                targetUid = AppGlobals.getPackageManager()
7754                                        .getPackageUid(targetPkg, targetUserId);
7755                            } catch (RemoteException e) {
7756                            }
7757                            if (targetUid != -1) {
7758                                final UriPermission perm = findOrCreateUriPermissionLocked(
7759                                        sourcePkg, targetPkg, targetUid,
7760                                        new GrantUri(sourceUserId, uri, prefix));
7761                                perm.initPersistedModes(modeFlags, createdTime);
7762                            }
7763                        } else {
7764                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7765                                    + " but instead found " + pi);
7766                        }
7767                    }
7768                }
7769            }
7770        } catch (FileNotFoundException e) {
7771            // Missing grants is okay
7772        } catch (IOException e) {
7773            Slog.wtf(TAG, "Failed reading Uri grants", e);
7774        } catch (XmlPullParserException e) {
7775            Slog.wtf(TAG, "Failed reading Uri grants", e);
7776        } finally {
7777            IoUtils.closeQuietly(fis);
7778        }
7779    }
7780
7781    /**
7782     * @param uri This uri must NOT contain an embedded userId.
7783     * @param userId The userId in which the uri is to be resolved.
7784     */
7785    @Override
7786    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7787        enforceNotIsolatedCaller("takePersistableUriPermission");
7788
7789        Preconditions.checkFlagsArgument(modeFlags,
7790                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7791
7792        synchronized (this) {
7793            final int callingUid = Binder.getCallingUid();
7794            boolean persistChanged = false;
7795            GrantUri grantUri = new GrantUri(userId, uri, false);
7796
7797            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7798                    new GrantUri(userId, uri, false));
7799            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7800                    new GrantUri(userId, uri, true));
7801
7802            final boolean exactValid = (exactPerm != null)
7803                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7804            final boolean prefixValid = (prefixPerm != null)
7805                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7806
7807            if (!(exactValid || prefixValid)) {
7808                throw new SecurityException("No persistable permission grants found for UID "
7809                        + callingUid + " and Uri " + grantUri.toSafeString());
7810            }
7811
7812            if (exactValid) {
7813                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7814            }
7815            if (prefixValid) {
7816                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7817            }
7818
7819            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7820
7821            if (persistChanged) {
7822                schedulePersistUriGrants();
7823            }
7824        }
7825    }
7826
7827    /**
7828     * @param uri This uri must NOT contain an embedded userId.
7829     * @param userId The userId in which the uri is to be resolved.
7830     */
7831    @Override
7832    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7833        enforceNotIsolatedCaller("releasePersistableUriPermission");
7834
7835        Preconditions.checkFlagsArgument(modeFlags,
7836                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7837
7838        synchronized (this) {
7839            final int callingUid = Binder.getCallingUid();
7840            boolean persistChanged = false;
7841
7842            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7843                    new GrantUri(userId, uri, false));
7844            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7845                    new GrantUri(userId, uri, true));
7846            if (exactPerm == null && prefixPerm == null) {
7847                throw new SecurityException("No permission grants found for UID " + callingUid
7848                        + " and Uri " + uri.toSafeString());
7849            }
7850
7851            if (exactPerm != null) {
7852                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7853                removeUriPermissionIfNeededLocked(exactPerm);
7854            }
7855            if (prefixPerm != null) {
7856                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7857                removeUriPermissionIfNeededLocked(prefixPerm);
7858            }
7859
7860            if (persistChanged) {
7861                schedulePersistUriGrants();
7862            }
7863        }
7864    }
7865
7866    /**
7867     * Prune any older {@link UriPermission} for the given UID until outstanding
7868     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7869     *
7870     * @return if any mutations occured that require persisting.
7871     */
7872    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7873        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7874        if (perms == null) return false;
7875        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7876
7877        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7878        for (UriPermission perm : perms.values()) {
7879            if (perm.persistedModeFlags != 0) {
7880                persisted.add(perm);
7881            }
7882        }
7883
7884        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7885        if (trimCount <= 0) return false;
7886
7887        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7888        for (int i = 0; i < trimCount; i++) {
7889            final UriPermission perm = persisted.get(i);
7890
7891            if (DEBUG_URI_PERMISSION) {
7892                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7893            }
7894
7895            perm.releasePersistableModes(~0);
7896            removeUriPermissionIfNeededLocked(perm);
7897        }
7898
7899        return true;
7900    }
7901
7902    @Override
7903    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7904            String packageName, boolean incoming) {
7905        enforceNotIsolatedCaller("getPersistedUriPermissions");
7906        Preconditions.checkNotNull(packageName, "packageName");
7907
7908        final int callingUid = Binder.getCallingUid();
7909        final IPackageManager pm = AppGlobals.getPackageManager();
7910        try {
7911            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7912            if (packageUid != callingUid) {
7913                throw new SecurityException(
7914                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7915            }
7916        } catch (RemoteException e) {
7917            throw new SecurityException("Failed to verify package name ownership");
7918        }
7919
7920        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7921        synchronized (this) {
7922            if (incoming) {
7923                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7924                        callingUid);
7925                if (perms == null) {
7926                    Slog.w(TAG, "No permission grants found for " + packageName);
7927                } else {
7928                    for (UriPermission perm : perms.values()) {
7929                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7930                            result.add(perm.buildPersistedPublicApiObject());
7931                        }
7932                    }
7933                }
7934            } else {
7935                final int size = mGrantedUriPermissions.size();
7936                for (int i = 0; i < size; i++) {
7937                    final ArrayMap<GrantUri, UriPermission> perms =
7938                            mGrantedUriPermissions.valueAt(i);
7939                    for (UriPermission perm : perms.values()) {
7940                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7941                            result.add(perm.buildPersistedPublicApiObject());
7942                        }
7943                    }
7944                }
7945            }
7946        }
7947        return new ParceledListSlice<android.content.UriPermission>(result);
7948    }
7949
7950    @Override
7951    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7952        synchronized (this) {
7953            ProcessRecord app =
7954                who != null ? getRecordForAppLocked(who) : null;
7955            if (app == null) return;
7956
7957            Message msg = Message.obtain();
7958            msg.what = WAIT_FOR_DEBUGGER_MSG;
7959            msg.obj = app;
7960            msg.arg1 = waiting ? 1 : 0;
7961            mHandler.sendMessage(msg);
7962        }
7963    }
7964
7965    @Override
7966    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7967        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7968        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7969        outInfo.availMem = Process.getFreeMemory();
7970        outInfo.totalMem = Process.getTotalMemory();
7971        outInfo.threshold = homeAppMem;
7972        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7973        outInfo.hiddenAppThreshold = cachedAppMem;
7974        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7975                ProcessList.SERVICE_ADJ);
7976        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7977                ProcessList.VISIBLE_APP_ADJ);
7978        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7979                ProcessList.FOREGROUND_APP_ADJ);
7980    }
7981
7982    // =========================================================
7983    // TASK MANAGEMENT
7984    // =========================================================
7985
7986    @Override
7987    public List<IAppTask> getAppTasks(String callingPackage) {
7988        int callingUid = Binder.getCallingUid();
7989        long ident = Binder.clearCallingIdentity();
7990
7991        synchronized(this) {
7992            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7993            try {
7994                if (localLOGV) Slog.v(TAG, "getAppTasks");
7995
7996                final int N = mRecentTasks.size();
7997                for (int i = 0; i < N; i++) {
7998                    TaskRecord tr = mRecentTasks.get(i);
7999                    // Skip tasks that do not match the caller.  We don't need to verify
8000                    // callingPackage, because we are also limiting to callingUid and know
8001                    // that will limit to the correct security sandbox.
8002                    if (tr.effectiveUid != callingUid) {
8003                        continue;
8004                    }
8005                    Intent intent = tr.getBaseIntent();
8006                    if (intent == null ||
8007                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8008                        continue;
8009                    }
8010                    ActivityManager.RecentTaskInfo taskInfo =
8011                            createRecentTaskInfoFromTaskRecord(tr);
8012                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8013                    list.add(taskImpl);
8014                }
8015            } finally {
8016                Binder.restoreCallingIdentity(ident);
8017            }
8018            return list;
8019        }
8020    }
8021
8022    @Override
8023    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8024        final int callingUid = Binder.getCallingUid();
8025        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8026
8027        synchronized(this) {
8028            if (localLOGV) Slog.v(
8029                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8030
8031            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8032                    callingUid);
8033
8034            // TODO: Improve with MRU list from all ActivityStacks.
8035            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8036        }
8037
8038        return list;
8039    }
8040
8041    TaskRecord getMostRecentTask() {
8042        return mRecentTasks.get(0);
8043    }
8044
8045    /**
8046     * Creates a new RecentTaskInfo from a TaskRecord.
8047     */
8048    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8049        // Update the task description to reflect any changes in the task stack
8050        tr.updateTaskDescription();
8051
8052        // Compose the recent task info
8053        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8054        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8055        rti.persistentId = tr.taskId;
8056        rti.baseIntent = new Intent(tr.getBaseIntent());
8057        rti.origActivity = tr.origActivity;
8058        rti.description = tr.lastDescription;
8059        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8060        rti.userId = tr.userId;
8061        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8062        rti.firstActiveTime = tr.firstActiveTime;
8063        rti.lastActiveTime = tr.lastActiveTime;
8064        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8065        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8066        return rti;
8067    }
8068
8069    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8070        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8071                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8072        if (!allowed) {
8073            if (checkPermission(android.Manifest.permission.GET_TASKS,
8074                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8075                // Temporary compatibility: some existing apps on the system image may
8076                // still be requesting the old permission and not switched to the new
8077                // one; if so, we'll still allow them full access.  This means we need
8078                // to see if they are holding the old permission and are a system app.
8079                try {
8080                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8081                        allowed = true;
8082                        Slog.w(TAG, caller + ": caller " + callingUid
8083                                + " is using old GET_TASKS but privileged; allowing");
8084                    }
8085                } catch (RemoteException e) {
8086                }
8087            }
8088        }
8089        if (!allowed) {
8090            Slog.w(TAG, caller + ": caller " + callingUid
8091                    + " does not hold GET_TASKS; limiting output");
8092        }
8093        return allowed;
8094    }
8095
8096    @Override
8097    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8098        final int callingUid = Binder.getCallingUid();
8099        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8100                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8101
8102        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8103        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8104        synchronized (this) {
8105            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8106                    callingUid);
8107            final boolean detailed = checkCallingPermission(
8108                    android.Manifest.permission.GET_DETAILED_TASKS)
8109                    == PackageManager.PERMISSION_GRANTED;
8110
8111            final int N = mRecentTasks.size();
8112            ArrayList<ActivityManager.RecentTaskInfo> res
8113                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8114                            maxNum < N ? maxNum : N);
8115
8116            final Set<Integer> includedUsers;
8117            if (includeProfiles) {
8118                includedUsers = getProfileIdsLocked(userId);
8119            } else {
8120                includedUsers = new HashSet<Integer>();
8121            }
8122            includedUsers.add(Integer.valueOf(userId));
8123
8124            for (int i=0; i<N && maxNum > 0; i++) {
8125                TaskRecord tr = mRecentTasks.get(i);
8126                // Only add calling user or related users recent tasks
8127                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8128                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8129                    continue;
8130                }
8131
8132                // Return the entry if desired by the caller.  We always return
8133                // the first entry, because callers always expect this to be the
8134                // foreground app.  We may filter others if the caller has
8135                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8136                // we should exclude the entry.
8137
8138                if (i == 0
8139                        || withExcluded
8140                        || (tr.intent == null)
8141                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8142                                == 0)) {
8143                    if (!allowed) {
8144                        // If the caller doesn't have the GET_TASKS permission, then only
8145                        // allow them to see a small subset of tasks -- their own and home.
8146                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8147                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8148                            continue;
8149                        }
8150                    }
8151                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8152                        if (tr.stack != null && tr.stack.isHomeStack()) {
8153                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8154                            continue;
8155                        }
8156                    }
8157                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8158                        // Don't include auto remove tasks that are finished or finishing.
8159                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8160                                + tr);
8161                        continue;
8162                    }
8163                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8164                            && !tr.isAvailable) {
8165                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8166                        continue;
8167                    }
8168
8169                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8170                    if (!detailed) {
8171                        rti.baseIntent.replaceExtras((Bundle)null);
8172                    }
8173
8174                    res.add(rti);
8175                    maxNum--;
8176                }
8177            }
8178            return res;
8179        }
8180    }
8181
8182    private TaskRecord recentTaskForIdLocked(int id) {
8183        final int N = mRecentTasks.size();
8184            for (int i=0; i<N; i++) {
8185                TaskRecord tr = mRecentTasks.get(i);
8186                if (tr.taskId == id) {
8187                    return tr;
8188                }
8189            }
8190            return null;
8191    }
8192
8193    @Override
8194    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8195        synchronized (this) {
8196            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8197                    "getTaskThumbnail()");
8198            TaskRecord tr = recentTaskForIdLocked(id);
8199            if (tr != null) {
8200                return tr.getTaskThumbnailLocked();
8201            }
8202        }
8203        return null;
8204    }
8205
8206    @Override
8207    public int addAppTask(IBinder activityToken, Intent intent,
8208            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8209        final int callingUid = Binder.getCallingUid();
8210        final long callingIdent = Binder.clearCallingIdentity();
8211
8212        try {
8213            synchronized (this) {
8214                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8215                if (r == null) {
8216                    throw new IllegalArgumentException("Activity does not exist; token="
8217                            + activityToken);
8218                }
8219                ComponentName comp = intent.getComponent();
8220                if (comp == null) {
8221                    throw new IllegalArgumentException("Intent " + intent
8222                            + " must specify explicit component");
8223                }
8224                if (thumbnail.getWidth() != mThumbnailWidth
8225                        || thumbnail.getHeight() != mThumbnailHeight) {
8226                    throw new IllegalArgumentException("Bad thumbnail size: got "
8227                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8228                            + mThumbnailWidth + "x" + mThumbnailHeight);
8229                }
8230                if (intent.getSelector() != null) {
8231                    intent.setSelector(null);
8232                }
8233                if (intent.getSourceBounds() != null) {
8234                    intent.setSourceBounds(null);
8235                }
8236                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8237                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8238                        // The caller has added this as an auto-remove task...  that makes no
8239                        // sense, so turn off auto-remove.
8240                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8241                    }
8242                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8243                    // Must be a new task.
8244                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8245                }
8246                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8247                    mLastAddedTaskActivity = null;
8248                }
8249                ActivityInfo ainfo = mLastAddedTaskActivity;
8250                if (ainfo == null) {
8251                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8252                            comp, 0, UserHandle.getUserId(callingUid));
8253                    if (ainfo.applicationInfo.uid != callingUid) {
8254                        throw new SecurityException(
8255                                "Can't add task for another application: target uid="
8256                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8257                    }
8258                }
8259
8260                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8261                        intent, description);
8262
8263                int trimIdx = trimRecentsForTask(task, false);
8264                if (trimIdx >= 0) {
8265                    // If this would have caused a trim, then we'll abort because that
8266                    // means it would be added at the end of the list but then just removed.
8267                    return -1;
8268                }
8269
8270                final int N = mRecentTasks.size();
8271                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8272                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8273                    tr.removedFromRecents(mTaskPersister);
8274                }
8275
8276                task.inRecents = true;
8277                mRecentTasks.add(task);
8278                r.task.stack.addTask(task, false, false);
8279
8280                task.setLastThumbnail(thumbnail);
8281                task.freeLastThumbnail();
8282
8283                return task.taskId;
8284            }
8285        } finally {
8286            Binder.restoreCallingIdentity(callingIdent);
8287        }
8288    }
8289
8290    @Override
8291    public Point getAppTaskThumbnailSize() {
8292        synchronized (this) {
8293            return new Point(mThumbnailWidth,  mThumbnailHeight);
8294        }
8295    }
8296
8297    @Override
8298    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8299        synchronized (this) {
8300            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8301            if (r != null) {
8302                r.setTaskDescription(td);
8303                r.task.updateTaskDescription();
8304            }
8305        }
8306    }
8307
8308    @Override
8309    public Bitmap getTaskDescriptionIcon(String filename) {
8310        if (!FileUtils.isValidExtFilename(filename)
8311                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8312            throw new IllegalArgumentException("Bad filename: " + filename);
8313        }
8314        return mTaskPersister.getTaskDescriptionIcon(filename);
8315    }
8316
8317    @Override
8318    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8319            throws RemoteException {
8320        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8321                opts.getCustomInPlaceResId() == 0) {
8322            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8323                    "with valid animation");
8324        }
8325        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8326        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8327                opts.getCustomInPlaceResId());
8328        mWindowManager.executeAppTransition();
8329    }
8330
8331    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8332        mRecentTasks.remove(tr);
8333        tr.removedFromRecents(mTaskPersister);
8334        ComponentName component = tr.getBaseIntent().getComponent();
8335        if (component == null) {
8336            Slog.w(TAG, "No component for base intent of task: " + tr);
8337            return;
8338        }
8339
8340        if (!killProcess) {
8341            return;
8342        }
8343
8344        // Determine if the process(es) for this task should be killed.
8345        final String pkg = component.getPackageName();
8346        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8347        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8348        for (int i = 0; i < pmap.size(); i++) {
8349
8350            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8351            for (int j = 0; j < uids.size(); j++) {
8352                ProcessRecord proc = uids.valueAt(j);
8353                if (proc.userId != tr.userId) {
8354                    // Don't kill process for a different user.
8355                    continue;
8356                }
8357                if (proc == mHomeProcess) {
8358                    // Don't kill the home process along with tasks from the same package.
8359                    continue;
8360                }
8361                if (!proc.pkgList.containsKey(pkg)) {
8362                    // Don't kill process that is not associated with this task.
8363                    continue;
8364                }
8365
8366                for (int k = 0; k < proc.activities.size(); k++) {
8367                    TaskRecord otherTask = proc.activities.get(k).task;
8368                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8369                        // Don't kill process(es) that has an activity in a different task that is
8370                        // also in recents.
8371                        return;
8372                    }
8373                }
8374
8375                // Add process to kill list.
8376                procsToKill.add(proc);
8377            }
8378        }
8379
8380        // Find any running services associated with this app and stop if needed.
8381        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8382
8383        // Kill the running processes.
8384        for (int i = 0; i < procsToKill.size(); i++) {
8385            ProcessRecord pr = procsToKill.get(i);
8386            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8387                pr.kill("remove task", true);
8388            } else {
8389                pr.waitingToKill = "remove task";
8390            }
8391        }
8392    }
8393
8394    /**
8395     * Removes the task with the specified task id.
8396     *
8397     * @param taskId Identifier of the task to be removed.
8398     * @param killProcess Kill any process associated with the task if possible.
8399     * @return Returns true if the given task was found and removed.
8400     */
8401    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8402        TaskRecord tr = recentTaskForIdLocked(taskId);
8403        if (tr != null) {
8404            tr.removeTaskActivitiesLocked();
8405            cleanUpRemovedTaskLocked(tr, killProcess);
8406            if (tr.isPersistable) {
8407                notifyTaskPersisterLocked(null, true);
8408            }
8409            return true;
8410        }
8411        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8412        return false;
8413    }
8414
8415    @Override
8416    public boolean removeTask(int taskId) {
8417        synchronized (this) {
8418            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8419                    "removeTask()");
8420            long ident = Binder.clearCallingIdentity();
8421            try {
8422                return removeTaskByIdLocked(taskId, true);
8423            } finally {
8424                Binder.restoreCallingIdentity(ident);
8425            }
8426        }
8427    }
8428
8429    /**
8430     * TODO: Add mController hook
8431     */
8432    @Override
8433    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8434        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8435                "moveTaskToFront()");
8436
8437        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8438        synchronized(this) {
8439            moveTaskToFrontLocked(taskId, flags, options);
8440        }
8441    }
8442
8443    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8444        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8445                Binder.getCallingUid(), -1, -1, "Task to front")) {
8446            ActivityOptions.abort(options);
8447            return;
8448        }
8449        final long origId = Binder.clearCallingIdentity();
8450        try {
8451            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8452            if (task == null) {
8453                return;
8454            }
8455            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8456                mStackSupervisor.showLockTaskToast();
8457                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8458                return;
8459            }
8460            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8461            if (prev != null && prev.isRecentsActivity()) {
8462                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8463            }
8464            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8465        } finally {
8466            Binder.restoreCallingIdentity(origId);
8467        }
8468        ActivityOptions.abort(options);
8469    }
8470
8471    @Override
8472    public void moveTaskToBack(int taskId) {
8473        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8474                "moveTaskToBack()");
8475
8476        synchronized(this) {
8477            TaskRecord tr = recentTaskForIdLocked(taskId);
8478            if (tr != null) {
8479                if (tr == mStackSupervisor.mLockTaskModeTask) {
8480                    mStackSupervisor.showLockTaskToast();
8481                    return;
8482                }
8483                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8484                ActivityStack stack = tr.stack;
8485                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8486                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8487                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8488                        return;
8489                    }
8490                }
8491                final long origId = Binder.clearCallingIdentity();
8492                try {
8493                    stack.moveTaskToBackLocked(taskId, null);
8494                } finally {
8495                    Binder.restoreCallingIdentity(origId);
8496                }
8497            }
8498        }
8499    }
8500
8501    /**
8502     * Moves an activity, and all of the other activities within the same task, to the bottom
8503     * of the history stack.  The activity's order within the task is unchanged.
8504     *
8505     * @param token A reference to the activity we wish to move
8506     * @param nonRoot If false then this only works if the activity is the root
8507     *                of a task; if true it will work for any activity in a task.
8508     * @return Returns true if the move completed, false if not.
8509     */
8510    @Override
8511    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8512        enforceNotIsolatedCaller("moveActivityTaskToBack");
8513        synchronized(this) {
8514            final long origId = Binder.clearCallingIdentity();
8515            try {
8516                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8517                if (taskId >= 0) {
8518                    if ((mStackSupervisor.mLockTaskModeTask != null)
8519                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8520                        mStackSupervisor.showLockTaskToast();
8521                        return false;
8522                    }
8523                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8524                }
8525            } finally {
8526                Binder.restoreCallingIdentity(origId);
8527            }
8528        }
8529        return false;
8530    }
8531
8532    @Override
8533    public void moveTaskBackwards(int task) {
8534        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8535                "moveTaskBackwards()");
8536
8537        synchronized(this) {
8538            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8539                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8540                return;
8541            }
8542            final long origId = Binder.clearCallingIdentity();
8543            moveTaskBackwardsLocked(task);
8544            Binder.restoreCallingIdentity(origId);
8545        }
8546    }
8547
8548    private final void moveTaskBackwardsLocked(int task) {
8549        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8550    }
8551
8552    @Override
8553    public IBinder getHomeActivityToken() throws RemoteException {
8554        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8555                "getHomeActivityToken()");
8556        synchronized (this) {
8557            return mStackSupervisor.getHomeActivityToken();
8558        }
8559    }
8560
8561    @Override
8562    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8563            IActivityContainerCallback callback) throws RemoteException {
8564        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8565                "createActivityContainer()");
8566        synchronized (this) {
8567            if (parentActivityToken == null) {
8568                throw new IllegalArgumentException("parent token must not be null");
8569            }
8570            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8571            if (r == null) {
8572                return null;
8573            }
8574            if (callback == null) {
8575                throw new IllegalArgumentException("callback must not be null");
8576            }
8577            return mStackSupervisor.createActivityContainer(r, callback);
8578        }
8579    }
8580
8581    @Override
8582    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8583        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8584                "deleteActivityContainer()");
8585        synchronized (this) {
8586            mStackSupervisor.deleteActivityContainer(container);
8587        }
8588    }
8589
8590    @Override
8591    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8592            throws RemoteException {
8593        synchronized (this) {
8594            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8595            if (stack != null) {
8596                return stack.mActivityContainer;
8597            }
8598            return null;
8599        }
8600    }
8601
8602    @Override
8603    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8604        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8605                "moveTaskToStack()");
8606        if (stackId == HOME_STACK_ID) {
8607            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8608                    new RuntimeException("here").fillInStackTrace());
8609        }
8610        synchronized (this) {
8611            long ident = Binder.clearCallingIdentity();
8612            try {
8613                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8614                        + stackId + " toTop=" + toTop);
8615                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8616            } finally {
8617                Binder.restoreCallingIdentity(ident);
8618            }
8619        }
8620    }
8621
8622    @Override
8623    public void resizeStack(int stackBoxId, Rect bounds) {
8624        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8625                "resizeStackBox()");
8626        long ident = Binder.clearCallingIdentity();
8627        try {
8628            mWindowManager.resizeStack(stackBoxId, bounds);
8629        } finally {
8630            Binder.restoreCallingIdentity(ident);
8631        }
8632    }
8633
8634    @Override
8635    public List<StackInfo> getAllStackInfos() {
8636        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8637                "getAllStackInfos()");
8638        long ident = Binder.clearCallingIdentity();
8639        try {
8640            synchronized (this) {
8641                return mStackSupervisor.getAllStackInfosLocked();
8642            }
8643        } finally {
8644            Binder.restoreCallingIdentity(ident);
8645        }
8646    }
8647
8648    @Override
8649    public StackInfo getStackInfo(int stackId) {
8650        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8651                "getStackInfo()");
8652        long ident = Binder.clearCallingIdentity();
8653        try {
8654            synchronized (this) {
8655                return mStackSupervisor.getStackInfoLocked(stackId);
8656            }
8657        } finally {
8658            Binder.restoreCallingIdentity(ident);
8659        }
8660    }
8661
8662    @Override
8663    public boolean isInHomeStack(int taskId) {
8664        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8665                "getStackInfo()");
8666        long ident = Binder.clearCallingIdentity();
8667        try {
8668            synchronized (this) {
8669                TaskRecord tr = recentTaskForIdLocked(taskId);
8670                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8671            }
8672        } finally {
8673            Binder.restoreCallingIdentity(ident);
8674        }
8675    }
8676
8677    @Override
8678    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8679        synchronized(this) {
8680            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8681        }
8682    }
8683
8684    private boolean isLockTaskAuthorized(String pkg) {
8685        final DevicePolicyManager dpm = (DevicePolicyManager)
8686                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8687        try {
8688            int uid = mContext.getPackageManager().getPackageUid(pkg,
8689                    Binder.getCallingUserHandle().getIdentifier());
8690            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8691        } catch (NameNotFoundException e) {
8692            return false;
8693        }
8694    }
8695
8696    void startLockTaskMode(TaskRecord task) {
8697        final String pkg;
8698        synchronized (this) {
8699            pkg = task.intent.getComponent().getPackageName();
8700        }
8701        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8702        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8703            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8704                    StatusBarManagerInternal.class);
8705            if (statusBarManager != null) {
8706                statusBarManager.showScreenPinningRequest();
8707            }
8708            return;
8709        }
8710        long ident = Binder.clearCallingIdentity();
8711        try {
8712            synchronized (this) {
8713                // Since we lost lock on task, make sure it is still there.
8714                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8715                if (task != null) {
8716                    if (!isSystemInitiated
8717                            && ((mStackSupervisor.getFocusedStack() == null)
8718                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8719                        throw new IllegalArgumentException("Invalid task, not in foreground");
8720                    }
8721                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8722                }
8723            }
8724        } finally {
8725            Binder.restoreCallingIdentity(ident);
8726        }
8727    }
8728
8729    @Override
8730    public void startLockTaskMode(int taskId) {
8731        final TaskRecord task;
8732        long ident = Binder.clearCallingIdentity();
8733        try {
8734            synchronized (this) {
8735                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8736            }
8737        } finally {
8738            Binder.restoreCallingIdentity(ident);
8739        }
8740        if (task != null) {
8741            startLockTaskMode(task);
8742        }
8743    }
8744
8745    @Override
8746    public void startLockTaskMode(IBinder token) {
8747        final TaskRecord task;
8748        long ident = Binder.clearCallingIdentity();
8749        try {
8750            synchronized (this) {
8751                final ActivityRecord r = ActivityRecord.forToken(token);
8752                if (r == null) {
8753                    return;
8754                }
8755                task = r.task;
8756            }
8757        } finally {
8758            Binder.restoreCallingIdentity(ident);
8759        }
8760        if (task != null) {
8761            startLockTaskMode(task);
8762        }
8763    }
8764
8765    @Override
8766    public void startLockTaskModeOnCurrent() throws RemoteException {
8767        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8768                "startLockTaskModeOnCurrent");
8769        long ident = Binder.clearCallingIdentity();
8770        try {
8771            ActivityRecord r = null;
8772            synchronized (this) {
8773                r = mStackSupervisor.topRunningActivityLocked();
8774            }
8775            startLockTaskMode(r.task);
8776        } finally {
8777            Binder.restoreCallingIdentity(ident);
8778        }
8779    }
8780
8781    @Override
8782    public void stopLockTaskMode() {
8783        // Verify that the user matches the package of the intent for the TaskRecord
8784        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8785        // and stopLockTaskMode.
8786        final int callingUid = Binder.getCallingUid();
8787        if (callingUid != Process.SYSTEM_UID) {
8788            try {
8789                String pkg =
8790                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8791                int uid = mContext.getPackageManager().getPackageUid(pkg,
8792                        Binder.getCallingUserHandle().getIdentifier());
8793                if (uid != callingUid) {
8794                    throw new SecurityException("Invalid uid, expected " + uid);
8795                }
8796            } catch (NameNotFoundException e) {
8797                Log.d(TAG, "stopLockTaskMode " + e);
8798                return;
8799            }
8800        }
8801        long ident = Binder.clearCallingIdentity();
8802        try {
8803            Log.d(TAG, "stopLockTaskMode");
8804            // Stop lock task
8805            synchronized (this) {
8806                mStackSupervisor.setLockTaskModeLocked(null, false);
8807            }
8808        } finally {
8809            Binder.restoreCallingIdentity(ident);
8810        }
8811    }
8812
8813    @Override
8814    public void stopLockTaskModeOnCurrent() throws RemoteException {
8815        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8816                "stopLockTaskModeOnCurrent");
8817        long ident = Binder.clearCallingIdentity();
8818        try {
8819            stopLockTaskMode();
8820        } finally {
8821            Binder.restoreCallingIdentity(ident);
8822        }
8823    }
8824
8825    @Override
8826    public boolean isInLockTaskMode() {
8827        synchronized (this) {
8828            return mStackSupervisor.isInLockTaskMode();
8829        }
8830    }
8831
8832    // =========================================================
8833    // CONTENT PROVIDERS
8834    // =========================================================
8835
8836    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8837        List<ProviderInfo> providers = null;
8838        try {
8839            providers = AppGlobals.getPackageManager().
8840                queryContentProviders(app.processName, app.uid,
8841                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8842        } catch (RemoteException ex) {
8843        }
8844        if (DEBUG_MU)
8845            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8846        int userId = app.userId;
8847        if (providers != null) {
8848            int N = providers.size();
8849            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8850            for (int i=0; i<N; i++) {
8851                ProviderInfo cpi =
8852                    (ProviderInfo)providers.get(i);
8853                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8854                        cpi.name, cpi.flags);
8855                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8856                    // This is a singleton provider, but a user besides the
8857                    // default user is asking to initialize a process it runs
8858                    // in...  well, no, it doesn't actually run in this process,
8859                    // it runs in the process of the default user.  Get rid of it.
8860                    providers.remove(i);
8861                    N--;
8862                    i--;
8863                    continue;
8864                }
8865
8866                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8867                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8868                if (cpr == null) {
8869                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8870                    mProviderMap.putProviderByClass(comp, cpr);
8871                }
8872                if (DEBUG_MU)
8873                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8874                app.pubProviders.put(cpi.name, cpr);
8875                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8876                    // Don't add this if it is a platform component that is marked
8877                    // to run in multiple processes, because this is actually
8878                    // part of the framework so doesn't make sense to track as a
8879                    // separate apk in the process.
8880                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8881                            mProcessStats);
8882                }
8883                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8884            }
8885        }
8886        return providers;
8887    }
8888
8889    /**
8890     * Check if {@link ProcessRecord} has a possible chance at accessing the
8891     * given {@link ProviderInfo}. Final permission checking is always done
8892     * in {@link ContentProvider}.
8893     */
8894    private final String checkContentProviderPermissionLocked(
8895            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8896        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8897        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8898        boolean checkedGrants = false;
8899        if (checkUser) {
8900            // Looking for cross-user grants before enforcing the typical cross-users permissions
8901            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8902            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8903                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8904                    return null;
8905                }
8906                checkedGrants = true;
8907            }
8908            userId = handleIncomingUser(callingPid, callingUid, userId,
8909                    false, ALLOW_NON_FULL,
8910                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8911            if (userId != tmpTargetUserId) {
8912                // When we actually went to determine the final targer user ID, this ended
8913                // up different than our initial check for the authority.  This is because
8914                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8915                // SELF.  So we need to re-check the grants again.
8916                checkedGrants = false;
8917            }
8918        }
8919        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8920                cpi.applicationInfo.uid, cpi.exported)
8921                == PackageManager.PERMISSION_GRANTED) {
8922            return null;
8923        }
8924        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8925                cpi.applicationInfo.uid, cpi.exported)
8926                == PackageManager.PERMISSION_GRANTED) {
8927            return null;
8928        }
8929
8930        PathPermission[] pps = cpi.pathPermissions;
8931        if (pps != null) {
8932            int i = pps.length;
8933            while (i > 0) {
8934                i--;
8935                PathPermission pp = pps[i];
8936                String pprperm = pp.getReadPermission();
8937                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8938                        cpi.applicationInfo.uid, cpi.exported)
8939                        == PackageManager.PERMISSION_GRANTED) {
8940                    return null;
8941                }
8942                String ppwperm = pp.getWritePermission();
8943                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8944                        cpi.applicationInfo.uid, cpi.exported)
8945                        == PackageManager.PERMISSION_GRANTED) {
8946                    return null;
8947                }
8948            }
8949        }
8950        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8951            return null;
8952        }
8953
8954        String msg;
8955        if (!cpi.exported) {
8956            msg = "Permission Denial: opening provider " + cpi.name
8957                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8958                    + ", uid=" + callingUid + ") that is not exported from uid "
8959                    + cpi.applicationInfo.uid;
8960        } else {
8961            msg = "Permission Denial: opening provider " + cpi.name
8962                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8963                    + ", uid=" + callingUid + ") requires "
8964                    + cpi.readPermission + " or " + cpi.writePermission;
8965        }
8966        Slog.w(TAG, msg);
8967        return msg;
8968    }
8969
8970    /**
8971     * Returns if the ContentProvider has granted a uri to callingUid
8972     */
8973    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8974        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8975        if (perms != null) {
8976            for (int i=perms.size()-1; i>=0; i--) {
8977                GrantUri grantUri = perms.keyAt(i);
8978                if (grantUri.sourceUserId == userId || !checkUser) {
8979                    if (matchesProvider(grantUri.uri, cpi)) {
8980                        return true;
8981                    }
8982                }
8983            }
8984        }
8985        return false;
8986    }
8987
8988    /**
8989     * Returns true if the uri authority is one of the authorities specified in the provider.
8990     */
8991    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8992        String uriAuth = uri.getAuthority();
8993        String cpiAuth = cpi.authority;
8994        if (cpiAuth.indexOf(';') == -1) {
8995            return cpiAuth.equals(uriAuth);
8996        }
8997        String[] cpiAuths = cpiAuth.split(";");
8998        int length = cpiAuths.length;
8999        for (int i = 0; i < length; i++) {
9000            if (cpiAuths[i].equals(uriAuth)) return true;
9001        }
9002        return false;
9003    }
9004
9005    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9006            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9007        if (r != null) {
9008            for (int i=0; i<r.conProviders.size(); i++) {
9009                ContentProviderConnection conn = r.conProviders.get(i);
9010                if (conn.provider == cpr) {
9011                    if (DEBUG_PROVIDER) Slog.v(TAG,
9012                            "Adding provider requested by "
9013                            + r.processName + " from process "
9014                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9015                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9016                    if (stable) {
9017                        conn.stableCount++;
9018                        conn.numStableIncs++;
9019                    } else {
9020                        conn.unstableCount++;
9021                        conn.numUnstableIncs++;
9022                    }
9023                    return conn;
9024                }
9025            }
9026            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9027            if (stable) {
9028                conn.stableCount = 1;
9029                conn.numStableIncs = 1;
9030            } else {
9031                conn.unstableCount = 1;
9032                conn.numUnstableIncs = 1;
9033            }
9034            cpr.connections.add(conn);
9035            r.conProviders.add(conn);
9036            return conn;
9037        }
9038        cpr.addExternalProcessHandleLocked(externalProcessToken);
9039        return null;
9040    }
9041
9042    boolean decProviderCountLocked(ContentProviderConnection conn,
9043            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9044        if (conn != null) {
9045            cpr = conn.provider;
9046            if (DEBUG_PROVIDER) Slog.v(TAG,
9047                    "Removing provider requested by "
9048                    + conn.client.processName + " from process "
9049                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9050                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9051            if (stable) {
9052                conn.stableCount--;
9053            } else {
9054                conn.unstableCount--;
9055            }
9056            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9057                cpr.connections.remove(conn);
9058                conn.client.conProviders.remove(conn);
9059                return true;
9060            }
9061            return false;
9062        }
9063        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9064        return false;
9065    }
9066
9067    private void checkTime(long startTime, String where) {
9068        long now = SystemClock.elapsedRealtime();
9069        if ((now-startTime) > 1000) {
9070            // If we are taking more than a second, log about it.
9071            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9072        }
9073    }
9074
9075    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9076            String name, IBinder token, boolean stable, int userId) {
9077        ContentProviderRecord cpr;
9078        ContentProviderConnection conn = null;
9079        ProviderInfo cpi = null;
9080
9081        synchronized(this) {
9082            long startTime = SystemClock.elapsedRealtime();
9083
9084            ProcessRecord r = null;
9085            if (caller != null) {
9086                r = getRecordForAppLocked(caller);
9087                if (r == null) {
9088                    throw new SecurityException(
9089                            "Unable to find app for caller " + caller
9090                          + " (pid=" + Binder.getCallingPid()
9091                          + ") when getting content provider " + name);
9092                }
9093            }
9094
9095            boolean checkCrossUser = true;
9096
9097            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9098
9099            // First check if this content provider has been published...
9100            cpr = mProviderMap.getProviderByName(name, userId);
9101            // If that didn't work, check if it exists for user 0 and then
9102            // verify that it's a singleton provider before using it.
9103            if (cpr == null && userId != UserHandle.USER_OWNER) {
9104                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9105                if (cpr != null) {
9106                    cpi = cpr.info;
9107                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9108                            cpi.name, cpi.flags)
9109                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9110                        userId = UserHandle.USER_OWNER;
9111                        checkCrossUser = false;
9112                    } else {
9113                        cpr = null;
9114                        cpi = null;
9115                    }
9116                }
9117            }
9118
9119            boolean providerRunning = cpr != null;
9120            if (providerRunning) {
9121                cpi = cpr.info;
9122                String msg;
9123                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9124                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9125                        != null) {
9126                    throw new SecurityException(msg);
9127                }
9128                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9129
9130                if (r != null && cpr.canRunHere(r)) {
9131                    // This provider has been published or is in the process
9132                    // of being published...  but it is also allowed to run
9133                    // in the caller's process, so don't make a connection
9134                    // and just let the caller instantiate its own instance.
9135                    ContentProviderHolder holder = cpr.newHolder(null);
9136                    // don't give caller the provider object, it needs
9137                    // to make its own.
9138                    holder.provider = null;
9139                    return holder;
9140                }
9141
9142                final long origId = Binder.clearCallingIdentity();
9143
9144                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9145
9146                // In this case the provider instance already exists, so we can
9147                // return it right away.
9148                conn = incProviderCountLocked(r, cpr, token, stable);
9149                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9150                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9151                        // If this is a perceptible app accessing the provider,
9152                        // make sure to count it as being accessed and thus
9153                        // back up on the LRU list.  This is good because
9154                        // content providers are often expensive to start.
9155                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9156                        updateLruProcessLocked(cpr.proc, false, null);
9157                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9158                    }
9159                }
9160
9161                if (cpr.proc != null) {
9162                    if (false) {
9163                        if (cpr.name.flattenToShortString().equals(
9164                                "com.android.providers.calendar/.CalendarProvider2")) {
9165                            Slog.v(TAG, "****************** KILLING "
9166                                + cpr.name.flattenToShortString());
9167                            Process.killProcess(cpr.proc.pid);
9168                        }
9169                    }
9170                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9171                    boolean success = updateOomAdjLocked(cpr.proc);
9172                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9173                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9174                    // NOTE: there is still a race here where a signal could be
9175                    // pending on the process even though we managed to update its
9176                    // adj level.  Not sure what to do about this, but at least
9177                    // the race is now smaller.
9178                    if (!success) {
9179                        // Uh oh...  it looks like the provider's process
9180                        // has been killed on us.  We need to wait for a new
9181                        // process to be started, and make sure its death
9182                        // doesn't kill our process.
9183                        Slog.i(TAG,
9184                                "Existing provider " + cpr.name.flattenToShortString()
9185                                + " is crashing; detaching " + r);
9186                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9187                        checkTime(startTime, "getContentProviderImpl: before appDied");
9188                        appDiedLocked(cpr.proc);
9189                        checkTime(startTime, "getContentProviderImpl: after appDied");
9190                        if (!lastRef) {
9191                            // This wasn't the last ref our process had on
9192                            // the provider...  we have now been killed, bail.
9193                            return null;
9194                        }
9195                        providerRunning = false;
9196                        conn = null;
9197                    }
9198                }
9199
9200                Binder.restoreCallingIdentity(origId);
9201            }
9202
9203            boolean singleton;
9204            if (!providerRunning) {
9205                try {
9206                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9207                    cpi = AppGlobals.getPackageManager().
9208                        resolveContentProvider(name,
9209                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9210                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9211                } catch (RemoteException ex) {
9212                }
9213                if (cpi == null) {
9214                    return null;
9215                }
9216                // If the provider is a singleton AND
9217                // (it's a call within the same user || the provider is a
9218                // privileged app)
9219                // Then allow connecting to the singleton provider
9220                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9221                        cpi.name, cpi.flags)
9222                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9223                if (singleton) {
9224                    userId = UserHandle.USER_OWNER;
9225                }
9226                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9227                checkTime(startTime, "getContentProviderImpl: got app info for user");
9228
9229                String msg;
9230                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9231                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9232                        != null) {
9233                    throw new SecurityException(msg);
9234                }
9235                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9236
9237                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9238                        && !cpi.processName.equals("system")) {
9239                    // If this content provider does not run in the system
9240                    // process, and the system is not yet ready to run other
9241                    // processes, then fail fast instead of hanging.
9242                    throw new IllegalArgumentException(
9243                            "Attempt to launch content provider before system ready");
9244                }
9245
9246                // Make sure that the user who owns this provider is started.  If not,
9247                // we don't want to allow it to run.
9248                if (mStartedUsers.get(userId) == null) {
9249                    Slog.w(TAG, "Unable to launch app "
9250                            + cpi.applicationInfo.packageName + "/"
9251                            + cpi.applicationInfo.uid + " for provider "
9252                            + name + ": user " + userId + " is stopped");
9253                    return null;
9254                }
9255
9256                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9257                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9258                cpr = mProviderMap.getProviderByClass(comp, userId);
9259                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9260                final boolean firstClass = cpr == null;
9261                if (firstClass) {
9262                    final long ident = Binder.clearCallingIdentity();
9263                    try {
9264                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9265                        ApplicationInfo ai =
9266                            AppGlobals.getPackageManager().
9267                                getApplicationInfo(
9268                                        cpi.applicationInfo.packageName,
9269                                        STOCK_PM_FLAGS, userId);
9270                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9271                        if (ai == null) {
9272                            Slog.w(TAG, "No package info for content provider "
9273                                    + cpi.name);
9274                            return null;
9275                        }
9276                        ai = getAppInfoForUser(ai, userId);
9277                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9278                    } catch (RemoteException ex) {
9279                        // pm is in same process, this will never happen.
9280                    } finally {
9281                        Binder.restoreCallingIdentity(ident);
9282                    }
9283                }
9284
9285                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9286
9287                if (r != null && cpr.canRunHere(r)) {
9288                    // If this is a multiprocess provider, then just return its
9289                    // info and allow the caller to instantiate it.  Only do
9290                    // this if the provider is the same user as the caller's
9291                    // process, or can run as root (so can be in any process).
9292                    return cpr.newHolder(null);
9293                }
9294
9295                if (DEBUG_PROVIDER) {
9296                    RuntimeException e = new RuntimeException("here");
9297                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9298                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9299                }
9300
9301                // This is single process, and our app is now connecting to it.
9302                // See if we are already in the process of launching this
9303                // provider.
9304                final int N = mLaunchingProviders.size();
9305                int i;
9306                for (i=0; i<N; i++) {
9307                    if (mLaunchingProviders.get(i) == cpr) {
9308                        break;
9309                    }
9310                }
9311
9312                // If the provider is not already being launched, then get it
9313                // started.
9314                if (i >= N) {
9315                    final long origId = Binder.clearCallingIdentity();
9316
9317                    try {
9318                        // Content provider is now in use, its package can't be stopped.
9319                        try {
9320                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9321                            AppGlobals.getPackageManager().setPackageStoppedState(
9322                                    cpr.appInfo.packageName, false, userId);
9323                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9324                        } catch (RemoteException e) {
9325                        } catch (IllegalArgumentException e) {
9326                            Slog.w(TAG, "Failed trying to unstop package "
9327                                    + cpr.appInfo.packageName + ": " + e);
9328                        }
9329
9330                        // Use existing process if already started
9331                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9332                        ProcessRecord proc = getProcessRecordLocked(
9333                                cpi.processName, cpr.appInfo.uid, false);
9334                        if (proc != null && proc.thread != null) {
9335                            if (DEBUG_PROVIDER) {
9336                                Slog.d(TAG, "Installing in existing process " + proc);
9337                            }
9338                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9339                            proc.pubProviders.put(cpi.name, cpr);
9340                            try {
9341                                proc.thread.scheduleInstallProvider(cpi);
9342                            } catch (RemoteException e) {
9343                            }
9344                        } else {
9345                            checkTime(startTime, "getContentProviderImpl: before start process");
9346                            proc = startProcessLocked(cpi.processName,
9347                                    cpr.appInfo, false, 0, "content provider",
9348                                    new ComponentName(cpi.applicationInfo.packageName,
9349                                            cpi.name), false, false, false);
9350                            checkTime(startTime, "getContentProviderImpl: after start process");
9351                            if (proc == null) {
9352                                Slog.w(TAG, "Unable to launch app "
9353                                        + cpi.applicationInfo.packageName + "/"
9354                                        + cpi.applicationInfo.uid + " for provider "
9355                                        + name + ": process is bad");
9356                                return null;
9357                            }
9358                        }
9359                        cpr.launchingApp = proc;
9360                        mLaunchingProviders.add(cpr);
9361                    } finally {
9362                        Binder.restoreCallingIdentity(origId);
9363                    }
9364                }
9365
9366                checkTime(startTime, "getContentProviderImpl: updating data structures");
9367
9368                // Make sure the provider is published (the same provider class
9369                // may be published under multiple names).
9370                if (firstClass) {
9371                    mProviderMap.putProviderByClass(comp, cpr);
9372                }
9373
9374                mProviderMap.putProviderByName(name, cpr);
9375                conn = incProviderCountLocked(r, cpr, token, stable);
9376                if (conn != null) {
9377                    conn.waiting = true;
9378                }
9379            }
9380            checkTime(startTime, "getContentProviderImpl: done!");
9381        }
9382
9383        // Wait for the provider to be published...
9384        synchronized (cpr) {
9385            while (cpr.provider == null) {
9386                if (cpr.launchingApp == null) {
9387                    Slog.w(TAG, "Unable to launch app "
9388                            + cpi.applicationInfo.packageName + "/"
9389                            + cpi.applicationInfo.uid + " for provider "
9390                            + name + ": launching app became null");
9391                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9392                            UserHandle.getUserId(cpi.applicationInfo.uid),
9393                            cpi.applicationInfo.packageName,
9394                            cpi.applicationInfo.uid, name);
9395                    return null;
9396                }
9397                try {
9398                    if (DEBUG_MU) {
9399                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9400                                + cpr.launchingApp);
9401                    }
9402                    if (conn != null) {
9403                        conn.waiting = true;
9404                    }
9405                    cpr.wait();
9406                } catch (InterruptedException ex) {
9407                } finally {
9408                    if (conn != null) {
9409                        conn.waiting = false;
9410                    }
9411                }
9412            }
9413        }
9414        return cpr != null ? cpr.newHolder(conn) : null;
9415    }
9416
9417    @Override
9418    public final ContentProviderHolder getContentProvider(
9419            IApplicationThread caller, String name, int userId, boolean stable) {
9420        enforceNotIsolatedCaller("getContentProvider");
9421        if (caller == null) {
9422            String msg = "null IApplicationThread when getting content provider "
9423                    + name;
9424            Slog.w(TAG, msg);
9425            throw new SecurityException(msg);
9426        }
9427        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9428        // with cross-user grant.
9429        return getContentProviderImpl(caller, name, null, stable, userId);
9430    }
9431
9432    public ContentProviderHolder getContentProviderExternal(
9433            String name, int userId, IBinder token) {
9434        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9435            "Do not have permission in call getContentProviderExternal()");
9436        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9437                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9438        return getContentProviderExternalUnchecked(name, token, userId);
9439    }
9440
9441    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9442            IBinder token, int userId) {
9443        return getContentProviderImpl(null, name, token, true, userId);
9444    }
9445
9446    /**
9447     * Drop a content provider from a ProcessRecord's bookkeeping
9448     */
9449    public void removeContentProvider(IBinder connection, boolean stable) {
9450        enforceNotIsolatedCaller("removeContentProvider");
9451        long ident = Binder.clearCallingIdentity();
9452        try {
9453            synchronized (this) {
9454                ContentProviderConnection conn;
9455                try {
9456                    conn = (ContentProviderConnection)connection;
9457                } catch (ClassCastException e) {
9458                    String msg ="removeContentProvider: " + connection
9459                            + " not a ContentProviderConnection";
9460                    Slog.w(TAG, msg);
9461                    throw new IllegalArgumentException(msg);
9462                }
9463                if (conn == null) {
9464                    throw new NullPointerException("connection is null");
9465                }
9466                if (decProviderCountLocked(conn, null, null, stable)) {
9467                    updateOomAdjLocked();
9468                }
9469            }
9470        } finally {
9471            Binder.restoreCallingIdentity(ident);
9472        }
9473    }
9474
9475    public void removeContentProviderExternal(String name, IBinder token) {
9476        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9477            "Do not have permission in call removeContentProviderExternal()");
9478        int userId = UserHandle.getCallingUserId();
9479        long ident = Binder.clearCallingIdentity();
9480        try {
9481            removeContentProviderExternalUnchecked(name, token, userId);
9482        } finally {
9483            Binder.restoreCallingIdentity(ident);
9484        }
9485    }
9486
9487    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9488        synchronized (this) {
9489            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9490            if(cpr == null) {
9491                //remove from mProvidersByClass
9492                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9493                return;
9494            }
9495
9496            //update content provider record entry info
9497            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9498            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9499            if (localCpr.hasExternalProcessHandles()) {
9500                if (localCpr.removeExternalProcessHandleLocked(token)) {
9501                    updateOomAdjLocked();
9502                } else {
9503                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9504                            + " with no external reference for token: "
9505                            + token + ".");
9506                }
9507            } else {
9508                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9509                        + " with no external references.");
9510            }
9511        }
9512    }
9513
9514    public final void publishContentProviders(IApplicationThread caller,
9515            List<ContentProviderHolder> providers) {
9516        if (providers == null) {
9517            return;
9518        }
9519
9520        enforceNotIsolatedCaller("publishContentProviders");
9521        synchronized (this) {
9522            final ProcessRecord r = getRecordForAppLocked(caller);
9523            if (DEBUG_MU)
9524                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9525            if (r == null) {
9526                throw new SecurityException(
9527                        "Unable to find app for caller " + caller
9528                      + " (pid=" + Binder.getCallingPid()
9529                      + ") when publishing content providers");
9530            }
9531
9532            final long origId = Binder.clearCallingIdentity();
9533
9534            final int N = providers.size();
9535            for (int i=0; i<N; i++) {
9536                ContentProviderHolder src = providers.get(i);
9537                if (src == null || src.info == null || src.provider == null) {
9538                    continue;
9539                }
9540                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9541                if (DEBUG_MU)
9542                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9543                if (dst != null) {
9544                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9545                    mProviderMap.putProviderByClass(comp, dst);
9546                    String names[] = dst.info.authority.split(";");
9547                    for (int j = 0; j < names.length; j++) {
9548                        mProviderMap.putProviderByName(names[j], dst);
9549                    }
9550
9551                    int NL = mLaunchingProviders.size();
9552                    int j;
9553                    for (j=0; j<NL; j++) {
9554                        if (mLaunchingProviders.get(j) == dst) {
9555                            mLaunchingProviders.remove(j);
9556                            j--;
9557                            NL--;
9558                        }
9559                    }
9560                    synchronized (dst) {
9561                        dst.provider = src.provider;
9562                        dst.proc = r;
9563                        dst.notifyAll();
9564                    }
9565                    updateOomAdjLocked(r);
9566                }
9567            }
9568
9569            Binder.restoreCallingIdentity(origId);
9570        }
9571    }
9572
9573    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9574        ContentProviderConnection conn;
9575        try {
9576            conn = (ContentProviderConnection)connection;
9577        } catch (ClassCastException e) {
9578            String msg ="refContentProvider: " + connection
9579                    + " not a ContentProviderConnection";
9580            Slog.w(TAG, msg);
9581            throw new IllegalArgumentException(msg);
9582        }
9583        if (conn == null) {
9584            throw new NullPointerException("connection is null");
9585        }
9586
9587        synchronized (this) {
9588            if (stable > 0) {
9589                conn.numStableIncs += stable;
9590            }
9591            stable = conn.stableCount + stable;
9592            if (stable < 0) {
9593                throw new IllegalStateException("stableCount < 0: " + stable);
9594            }
9595
9596            if (unstable > 0) {
9597                conn.numUnstableIncs += unstable;
9598            }
9599            unstable = conn.unstableCount + unstable;
9600            if (unstable < 0) {
9601                throw new IllegalStateException("unstableCount < 0: " + unstable);
9602            }
9603
9604            if ((stable+unstable) <= 0) {
9605                throw new IllegalStateException("ref counts can't go to zero here: stable="
9606                        + stable + " unstable=" + unstable);
9607            }
9608            conn.stableCount = stable;
9609            conn.unstableCount = unstable;
9610            return !conn.dead;
9611        }
9612    }
9613
9614    public void unstableProviderDied(IBinder connection) {
9615        ContentProviderConnection conn;
9616        try {
9617            conn = (ContentProviderConnection)connection;
9618        } catch (ClassCastException e) {
9619            String msg ="refContentProvider: " + connection
9620                    + " not a ContentProviderConnection";
9621            Slog.w(TAG, msg);
9622            throw new IllegalArgumentException(msg);
9623        }
9624        if (conn == null) {
9625            throw new NullPointerException("connection is null");
9626        }
9627
9628        // Safely retrieve the content provider associated with the connection.
9629        IContentProvider provider;
9630        synchronized (this) {
9631            provider = conn.provider.provider;
9632        }
9633
9634        if (provider == null) {
9635            // Um, yeah, we're way ahead of you.
9636            return;
9637        }
9638
9639        // Make sure the caller is being honest with us.
9640        if (provider.asBinder().pingBinder()) {
9641            // Er, no, still looks good to us.
9642            synchronized (this) {
9643                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9644                        + " says " + conn + " died, but we don't agree");
9645                return;
9646            }
9647        }
9648
9649        // Well look at that!  It's dead!
9650        synchronized (this) {
9651            if (conn.provider.provider != provider) {
9652                // But something changed...  good enough.
9653                return;
9654            }
9655
9656            ProcessRecord proc = conn.provider.proc;
9657            if (proc == null || proc.thread == null) {
9658                // Seems like the process is already cleaned up.
9659                return;
9660            }
9661
9662            // As far as we're concerned, this is just like receiving a
9663            // death notification...  just a bit prematurely.
9664            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9665                    + ") early provider death");
9666            final long ident = Binder.clearCallingIdentity();
9667            try {
9668                appDiedLocked(proc);
9669            } finally {
9670                Binder.restoreCallingIdentity(ident);
9671            }
9672        }
9673    }
9674
9675    @Override
9676    public void appNotRespondingViaProvider(IBinder connection) {
9677        enforceCallingPermission(
9678                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9679
9680        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9681        if (conn == null) {
9682            Slog.w(TAG, "ContentProviderConnection is null");
9683            return;
9684        }
9685
9686        final ProcessRecord host = conn.provider.proc;
9687        if (host == null) {
9688            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9689            return;
9690        }
9691
9692        final long token = Binder.clearCallingIdentity();
9693        try {
9694            appNotResponding(host, null, null, false, "ContentProvider not responding");
9695        } finally {
9696            Binder.restoreCallingIdentity(token);
9697        }
9698    }
9699
9700    public final void installSystemProviders() {
9701        List<ProviderInfo> providers;
9702        synchronized (this) {
9703            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9704            providers = generateApplicationProvidersLocked(app);
9705            if (providers != null) {
9706                for (int i=providers.size()-1; i>=0; i--) {
9707                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9708                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9709                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9710                                + ": not system .apk");
9711                        providers.remove(i);
9712                    }
9713                }
9714            }
9715        }
9716        if (providers != null) {
9717            mSystemThread.installSystemProviders(providers);
9718        }
9719
9720        mCoreSettingsObserver = new CoreSettingsObserver(this);
9721
9722        //mUsageStatsService.monitorPackages();
9723    }
9724
9725    /**
9726     * Allows apps to retrieve the MIME type of a URI.
9727     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9728     * users, then it does not need permission to access the ContentProvider.
9729     * Either, it needs cross-user uri grants.
9730     *
9731     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9732     *
9733     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9734     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9735     */
9736    public String getProviderMimeType(Uri uri, int userId) {
9737        enforceNotIsolatedCaller("getProviderMimeType");
9738        final String name = uri.getAuthority();
9739        int callingUid = Binder.getCallingUid();
9740        int callingPid = Binder.getCallingPid();
9741        long ident = 0;
9742        boolean clearedIdentity = false;
9743        userId = unsafeConvertIncomingUser(userId);
9744        if (canClearIdentity(callingPid, callingUid, userId)) {
9745            clearedIdentity = true;
9746            ident = Binder.clearCallingIdentity();
9747        }
9748        ContentProviderHolder holder = null;
9749        try {
9750            holder = getContentProviderExternalUnchecked(name, null, userId);
9751            if (holder != null) {
9752                return holder.provider.getType(uri);
9753            }
9754        } catch (RemoteException e) {
9755            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9756            return null;
9757        } finally {
9758            // We need to clear the identity to call removeContentProviderExternalUnchecked
9759            if (!clearedIdentity) {
9760                ident = Binder.clearCallingIdentity();
9761            }
9762            try {
9763                if (holder != null) {
9764                    removeContentProviderExternalUnchecked(name, null, userId);
9765                }
9766            } finally {
9767                Binder.restoreCallingIdentity(ident);
9768            }
9769        }
9770
9771        return null;
9772    }
9773
9774    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9775        if (UserHandle.getUserId(callingUid) == userId) {
9776            return true;
9777        }
9778        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9779                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9780                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9781                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9782                return true;
9783        }
9784        return false;
9785    }
9786
9787    // =========================================================
9788    // GLOBAL MANAGEMENT
9789    // =========================================================
9790
9791    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9792            boolean isolated, int isolatedUid) {
9793        String proc = customProcess != null ? customProcess : info.processName;
9794        BatteryStatsImpl.Uid.Proc ps = null;
9795        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9796        int uid = info.uid;
9797        if (isolated) {
9798            if (isolatedUid == 0) {
9799                int userId = UserHandle.getUserId(uid);
9800                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9801                while (true) {
9802                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9803                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9804                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9805                    }
9806                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9807                    mNextIsolatedProcessUid++;
9808                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9809                        // No process for this uid, use it.
9810                        break;
9811                    }
9812                    stepsLeft--;
9813                    if (stepsLeft <= 0) {
9814                        return null;
9815                    }
9816                }
9817            } else {
9818                // Special case for startIsolatedProcess (internal only), where
9819                // the uid of the isolated process is specified by the caller.
9820                uid = isolatedUid;
9821            }
9822        }
9823        return new ProcessRecord(stats, info, proc, uid);
9824    }
9825
9826    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9827            String abiOverride) {
9828        ProcessRecord app;
9829        if (!isolated) {
9830            app = getProcessRecordLocked(info.processName, info.uid, true);
9831        } else {
9832            app = null;
9833        }
9834
9835        if (app == null) {
9836            app = newProcessRecordLocked(info, null, isolated, 0);
9837            mProcessNames.put(info.processName, app.uid, app);
9838            if (isolated) {
9839                mIsolatedProcesses.put(app.uid, app);
9840            }
9841            updateLruProcessLocked(app, false, null);
9842            updateOomAdjLocked();
9843        }
9844
9845        // This package really, really can not be stopped.
9846        try {
9847            AppGlobals.getPackageManager().setPackageStoppedState(
9848                    info.packageName, false, UserHandle.getUserId(app.uid));
9849        } catch (RemoteException e) {
9850        } catch (IllegalArgumentException e) {
9851            Slog.w(TAG, "Failed trying to unstop package "
9852                    + info.packageName + ": " + e);
9853        }
9854
9855        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9856                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9857            app.persistent = true;
9858            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9859        }
9860        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9861            mPersistentStartingProcesses.add(app);
9862            startProcessLocked(app, "added application", app.processName, abiOverride,
9863                    null /* entryPoint */, null /* entryPointArgs */);
9864        }
9865
9866        return app;
9867    }
9868
9869    public void unhandledBack() {
9870        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9871                "unhandledBack()");
9872
9873        synchronized(this) {
9874            final long origId = Binder.clearCallingIdentity();
9875            try {
9876                getFocusedStack().unhandledBackLocked();
9877            } finally {
9878                Binder.restoreCallingIdentity(origId);
9879            }
9880        }
9881    }
9882
9883    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9884        enforceNotIsolatedCaller("openContentUri");
9885        final int userId = UserHandle.getCallingUserId();
9886        String name = uri.getAuthority();
9887        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9888        ParcelFileDescriptor pfd = null;
9889        if (cph != null) {
9890            // We record the binder invoker's uid in thread-local storage before
9891            // going to the content provider to open the file.  Later, in the code
9892            // that handles all permissions checks, we look for this uid and use
9893            // that rather than the Activity Manager's own uid.  The effect is that
9894            // we do the check against the caller's permissions even though it looks
9895            // to the content provider like the Activity Manager itself is making
9896            // the request.
9897            sCallerIdentity.set(new Identity(
9898                    Binder.getCallingPid(), Binder.getCallingUid()));
9899            try {
9900                pfd = cph.provider.openFile(null, uri, "r", null);
9901            } catch (FileNotFoundException e) {
9902                // do nothing; pfd will be returned null
9903            } finally {
9904                // Ensure that whatever happens, we clean up the identity state
9905                sCallerIdentity.remove();
9906            }
9907
9908            // We've got the fd now, so we're done with the provider.
9909            removeContentProviderExternalUnchecked(name, null, userId);
9910        } else {
9911            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9912        }
9913        return pfd;
9914    }
9915
9916    // Actually is sleeping or shutting down or whatever else in the future
9917    // is an inactive state.
9918    public boolean isSleepingOrShuttingDown() {
9919        return isSleeping() || mShuttingDown;
9920    }
9921
9922    public boolean isSleeping() {
9923        return mSleeping;
9924    }
9925
9926    void goingToSleep() {
9927        synchronized(this) {
9928            mWentToSleep = true;
9929            goToSleepIfNeededLocked();
9930        }
9931    }
9932
9933    void finishRunningVoiceLocked() {
9934        if (mRunningVoice) {
9935            mRunningVoice = false;
9936            goToSleepIfNeededLocked();
9937        }
9938    }
9939
9940    void goToSleepIfNeededLocked() {
9941        if (mWentToSleep && !mRunningVoice) {
9942            if (!mSleeping) {
9943                mSleeping = true;
9944                mStackSupervisor.goingToSleepLocked();
9945
9946                // Initialize the wake times of all processes.
9947                checkExcessivePowerUsageLocked(false);
9948                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9949                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9950                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9951            }
9952        }
9953    }
9954
9955    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9956        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9957            // Never persist the home stack.
9958            return;
9959        }
9960        mTaskPersister.wakeup(task, flush);
9961    }
9962
9963    @Override
9964    public boolean shutdown(int timeout) {
9965        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9966                != PackageManager.PERMISSION_GRANTED) {
9967            throw new SecurityException("Requires permission "
9968                    + android.Manifest.permission.SHUTDOWN);
9969        }
9970
9971        boolean timedout = false;
9972
9973        synchronized(this) {
9974            mShuttingDown = true;
9975            updateEventDispatchingLocked();
9976            timedout = mStackSupervisor.shutdownLocked(timeout);
9977        }
9978
9979        mAppOpsService.shutdown();
9980        if (mUsageStatsService != null) {
9981            mUsageStatsService.prepareShutdown();
9982        }
9983        mBatteryStatsService.shutdown();
9984        synchronized (this) {
9985            mProcessStats.shutdownLocked();
9986        }
9987        notifyTaskPersisterLocked(null, true);
9988
9989        return timedout;
9990    }
9991
9992    public final void activitySlept(IBinder token) {
9993        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9994
9995        final long origId = Binder.clearCallingIdentity();
9996
9997        synchronized (this) {
9998            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9999            if (r != null) {
10000                mStackSupervisor.activitySleptLocked(r);
10001            }
10002        }
10003
10004        Binder.restoreCallingIdentity(origId);
10005    }
10006
10007    private String lockScreenShownToString() {
10008        switch (mLockScreenShown) {
10009            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10010            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10011            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10012            default: return "Unknown=" + mLockScreenShown;
10013        }
10014    }
10015
10016    void logLockScreen(String msg) {
10017        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10018                " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" +
10019                mWentToSleep + " mSleeping=" + mSleeping);
10020    }
10021
10022    void comeOutOfSleepIfNeededLocked() {
10023        if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) {
10024            if (mSleeping) {
10025                mSleeping = false;
10026                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10027            }
10028        }
10029    }
10030
10031    void wakingUp() {
10032        synchronized(this) {
10033            mWentToSleep = false;
10034            comeOutOfSleepIfNeededLocked();
10035        }
10036    }
10037
10038    void startRunningVoiceLocked() {
10039        if (!mRunningVoice) {
10040            mRunningVoice = true;
10041            comeOutOfSleepIfNeededLocked();
10042        }
10043    }
10044
10045    private void updateEventDispatchingLocked() {
10046        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10047    }
10048
10049    public void setLockScreenShown(boolean shown) {
10050        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10051                != PackageManager.PERMISSION_GRANTED) {
10052            throw new SecurityException("Requires permission "
10053                    + android.Manifest.permission.DEVICE_POWER);
10054        }
10055
10056        synchronized(this) {
10057            long ident = Binder.clearCallingIdentity();
10058            try {
10059                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10060                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10061                comeOutOfSleepIfNeededLocked();
10062            } finally {
10063                Binder.restoreCallingIdentity(ident);
10064            }
10065        }
10066    }
10067
10068    @Override
10069    public void stopAppSwitches() {
10070        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10071                != PackageManager.PERMISSION_GRANTED) {
10072            throw new SecurityException("Requires permission "
10073                    + android.Manifest.permission.STOP_APP_SWITCHES);
10074        }
10075
10076        synchronized(this) {
10077            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10078                    + APP_SWITCH_DELAY_TIME;
10079            mDidAppSwitch = false;
10080            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10081            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10082            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10083        }
10084    }
10085
10086    public void resumeAppSwitches() {
10087        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10088                != PackageManager.PERMISSION_GRANTED) {
10089            throw new SecurityException("Requires permission "
10090                    + android.Manifest.permission.STOP_APP_SWITCHES);
10091        }
10092
10093        synchronized(this) {
10094            // Note that we don't execute any pending app switches... we will
10095            // let those wait until either the timeout, or the next start
10096            // activity request.
10097            mAppSwitchesAllowedTime = 0;
10098        }
10099    }
10100
10101    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10102            int callingPid, int callingUid, String name) {
10103        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10104            return true;
10105        }
10106
10107        int perm = checkComponentPermission(
10108                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10109                sourceUid, -1, true);
10110        if (perm == PackageManager.PERMISSION_GRANTED) {
10111            return true;
10112        }
10113
10114        // If the actual IPC caller is different from the logical source, then
10115        // also see if they are allowed to control app switches.
10116        if (callingUid != -1 && callingUid != sourceUid) {
10117            perm = checkComponentPermission(
10118                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10119                    callingUid, -1, true);
10120            if (perm == PackageManager.PERMISSION_GRANTED) {
10121                return true;
10122            }
10123        }
10124
10125        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10126        return false;
10127    }
10128
10129    public void setDebugApp(String packageName, boolean waitForDebugger,
10130            boolean persistent) {
10131        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10132                "setDebugApp()");
10133
10134        long ident = Binder.clearCallingIdentity();
10135        try {
10136            // Note that this is not really thread safe if there are multiple
10137            // callers into it at the same time, but that's not a situation we
10138            // care about.
10139            if (persistent) {
10140                final ContentResolver resolver = mContext.getContentResolver();
10141                Settings.Global.putString(
10142                    resolver, Settings.Global.DEBUG_APP,
10143                    packageName);
10144                Settings.Global.putInt(
10145                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10146                    waitForDebugger ? 1 : 0);
10147            }
10148
10149            synchronized (this) {
10150                if (!persistent) {
10151                    mOrigDebugApp = mDebugApp;
10152                    mOrigWaitForDebugger = mWaitForDebugger;
10153                }
10154                mDebugApp = packageName;
10155                mWaitForDebugger = waitForDebugger;
10156                mDebugTransient = !persistent;
10157                if (packageName != null) {
10158                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10159                            false, UserHandle.USER_ALL, "set debug app");
10160                }
10161            }
10162        } finally {
10163            Binder.restoreCallingIdentity(ident);
10164        }
10165    }
10166
10167    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10168        synchronized (this) {
10169            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10170            if (!isDebuggable) {
10171                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10172                    throw new SecurityException("Process not debuggable: " + app.packageName);
10173                }
10174            }
10175
10176            mOpenGlTraceApp = processName;
10177        }
10178    }
10179
10180    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10181        synchronized (this) {
10182            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10183            if (!isDebuggable) {
10184                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10185                    throw new SecurityException("Process not debuggable: " + app.packageName);
10186                }
10187            }
10188            mProfileApp = processName;
10189            mProfileFile = profilerInfo.profileFile;
10190            if (mProfileFd != null) {
10191                try {
10192                    mProfileFd.close();
10193                } catch (IOException e) {
10194                }
10195                mProfileFd = null;
10196            }
10197            mProfileFd = profilerInfo.profileFd;
10198            mSamplingInterval = profilerInfo.samplingInterval;
10199            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10200            mProfileType = 0;
10201        }
10202    }
10203
10204    @Override
10205    public void setAlwaysFinish(boolean enabled) {
10206        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10207                "setAlwaysFinish()");
10208
10209        Settings.Global.putInt(
10210                mContext.getContentResolver(),
10211                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10212
10213        synchronized (this) {
10214            mAlwaysFinishActivities = enabled;
10215        }
10216    }
10217
10218    @Override
10219    public void setActivityController(IActivityController controller) {
10220        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10221                "setActivityController()");
10222        synchronized (this) {
10223            mController = controller;
10224            Watchdog.getInstance().setActivityController(controller);
10225        }
10226    }
10227
10228    @Override
10229    public void setUserIsMonkey(boolean userIsMonkey) {
10230        synchronized (this) {
10231            synchronized (mPidsSelfLocked) {
10232                final int callingPid = Binder.getCallingPid();
10233                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10234                if (precessRecord == null) {
10235                    throw new SecurityException("Unknown process: " + callingPid);
10236                }
10237                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10238                    throw new SecurityException("Only an instrumentation process "
10239                            + "with a UiAutomation can call setUserIsMonkey");
10240                }
10241            }
10242            mUserIsMonkey = userIsMonkey;
10243        }
10244    }
10245
10246    @Override
10247    public boolean isUserAMonkey() {
10248        synchronized (this) {
10249            // If there is a controller also implies the user is a monkey.
10250            return (mUserIsMonkey || mController != null);
10251        }
10252    }
10253
10254    public void requestBugReport() {
10255        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10256        SystemProperties.set("ctl.start", "bugreport");
10257    }
10258
10259    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10260        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10261    }
10262
10263    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10264        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10265            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10266        }
10267        return KEY_DISPATCHING_TIMEOUT;
10268    }
10269
10270    @Override
10271    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10272        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10273                != PackageManager.PERMISSION_GRANTED) {
10274            throw new SecurityException("Requires permission "
10275                    + android.Manifest.permission.FILTER_EVENTS);
10276        }
10277        ProcessRecord proc;
10278        long timeout;
10279        synchronized (this) {
10280            synchronized (mPidsSelfLocked) {
10281                proc = mPidsSelfLocked.get(pid);
10282            }
10283            timeout = getInputDispatchingTimeoutLocked(proc);
10284        }
10285
10286        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10287            return -1;
10288        }
10289
10290        return timeout;
10291    }
10292
10293    /**
10294     * Handle input dispatching timeouts.
10295     * Returns whether input dispatching should be aborted or not.
10296     */
10297    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10298            final ActivityRecord activity, final ActivityRecord parent,
10299            final boolean aboveSystem, String reason) {
10300        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10301                != PackageManager.PERMISSION_GRANTED) {
10302            throw new SecurityException("Requires permission "
10303                    + android.Manifest.permission.FILTER_EVENTS);
10304        }
10305
10306        final String annotation;
10307        if (reason == null) {
10308            annotation = "Input dispatching timed out";
10309        } else {
10310            annotation = "Input dispatching timed out (" + reason + ")";
10311        }
10312
10313        if (proc != null) {
10314            synchronized (this) {
10315                if (proc.debugging) {
10316                    return false;
10317                }
10318
10319                if (mDidDexOpt) {
10320                    // Give more time since we were dexopting.
10321                    mDidDexOpt = false;
10322                    return false;
10323                }
10324
10325                if (proc.instrumentationClass != null) {
10326                    Bundle info = new Bundle();
10327                    info.putString("shortMsg", "keyDispatchingTimedOut");
10328                    info.putString("longMsg", annotation);
10329                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10330                    return true;
10331                }
10332            }
10333            mHandler.post(new Runnable() {
10334                @Override
10335                public void run() {
10336                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10337                }
10338            });
10339        }
10340
10341        return true;
10342    }
10343
10344    public Bundle getAssistContextExtras(int requestType) {
10345        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10346                UserHandle.getCallingUserId());
10347        if (pae == null) {
10348            return null;
10349        }
10350        synchronized (pae) {
10351            while (!pae.haveResult) {
10352                try {
10353                    pae.wait();
10354                } catch (InterruptedException e) {
10355                }
10356            }
10357            if (pae.result != null) {
10358                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10359            }
10360        }
10361        synchronized (this) {
10362            mPendingAssistExtras.remove(pae);
10363            mHandler.removeCallbacks(pae);
10364        }
10365        return pae.extras;
10366    }
10367
10368    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10369            int userHandle) {
10370        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10371                "getAssistContextExtras()");
10372        PendingAssistExtras pae;
10373        Bundle extras = new Bundle();
10374        synchronized (this) {
10375            ActivityRecord activity = getFocusedStack().mResumedActivity;
10376            if (activity == null) {
10377                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10378                return null;
10379            }
10380            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10381            if (activity.app == null || activity.app.thread == null) {
10382                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10383                return null;
10384            }
10385            if (activity.app.pid == Binder.getCallingPid()) {
10386                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10387                return null;
10388            }
10389            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10390            try {
10391                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10392                        requestType);
10393                mPendingAssistExtras.add(pae);
10394                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10395            } catch (RemoteException e) {
10396                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10397                return null;
10398            }
10399            return pae;
10400        }
10401    }
10402
10403    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10404        PendingAssistExtras pae = (PendingAssistExtras)token;
10405        synchronized (pae) {
10406            pae.result = extras;
10407            pae.haveResult = true;
10408            pae.notifyAll();
10409            if (pae.intent == null) {
10410                // Caller is just waiting for the result.
10411                return;
10412            }
10413        }
10414
10415        // We are now ready to launch the assist activity.
10416        synchronized (this) {
10417            boolean exists = mPendingAssistExtras.remove(pae);
10418            mHandler.removeCallbacks(pae);
10419            if (!exists) {
10420                // Timed out.
10421                return;
10422            }
10423        }
10424        pae.intent.replaceExtras(extras);
10425        if (pae.hint != null) {
10426            pae.intent.putExtra(pae.hint, true);
10427        }
10428        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10429                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10430                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10431        closeSystemDialogs("assist");
10432        try {
10433            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10434        } catch (ActivityNotFoundException e) {
10435            Slog.w(TAG, "No activity to handle assist action.", e);
10436        }
10437    }
10438
10439    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10440        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10441    }
10442
10443    public void registerProcessObserver(IProcessObserver observer) {
10444        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10445                "registerProcessObserver()");
10446        synchronized (this) {
10447            mProcessObservers.register(observer);
10448        }
10449    }
10450
10451    @Override
10452    public void unregisterProcessObserver(IProcessObserver observer) {
10453        synchronized (this) {
10454            mProcessObservers.unregister(observer);
10455        }
10456    }
10457
10458    @Override
10459    public boolean convertFromTranslucent(IBinder token) {
10460        final long origId = Binder.clearCallingIdentity();
10461        try {
10462            synchronized (this) {
10463                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10464                if (r == null) {
10465                    return false;
10466                }
10467                final boolean translucentChanged = r.changeWindowTranslucency(true);
10468                if (translucentChanged) {
10469                    r.task.stack.releaseBackgroundResources();
10470                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10471                }
10472                mWindowManager.setAppFullscreen(token, true);
10473                return translucentChanged;
10474            }
10475        } finally {
10476            Binder.restoreCallingIdentity(origId);
10477        }
10478    }
10479
10480    @Override
10481    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10482        final long origId = Binder.clearCallingIdentity();
10483        try {
10484            synchronized (this) {
10485                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10486                if (r == null) {
10487                    return false;
10488                }
10489                int index = r.task.mActivities.lastIndexOf(r);
10490                if (index > 0) {
10491                    ActivityRecord under = r.task.mActivities.get(index - 1);
10492                    under.returningOptions = options;
10493                }
10494                final boolean translucentChanged = r.changeWindowTranslucency(false);
10495                if (translucentChanged) {
10496                    r.task.stack.convertToTranslucent(r);
10497                }
10498                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10499                mWindowManager.setAppFullscreen(token, false);
10500                return translucentChanged;
10501            }
10502        } finally {
10503            Binder.restoreCallingIdentity(origId);
10504        }
10505    }
10506
10507    @Override
10508    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10509        final long origId = Binder.clearCallingIdentity();
10510        try {
10511            synchronized (this) {
10512                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10513                if (r != null) {
10514                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10515                }
10516            }
10517            return false;
10518        } finally {
10519            Binder.restoreCallingIdentity(origId);
10520        }
10521    }
10522
10523    @Override
10524    public boolean isBackgroundVisibleBehind(IBinder token) {
10525        final long origId = Binder.clearCallingIdentity();
10526        try {
10527            synchronized (this) {
10528                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10529                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10530                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10531                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10532                return visible;
10533            }
10534        } finally {
10535            Binder.restoreCallingIdentity(origId);
10536        }
10537    }
10538
10539    @Override
10540    public ActivityOptions getActivityOptions(IBinder token) {
10541        final long origId = Binder.clearCallingIdentity();
10542        try {
10543            synchronized (this) {
10544                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10545                if (r != null) {
10546                    final ActivityOptions activityOptions = r.pendingOptions;
10547                    r.pendingOptions = null;
10548                    return activityOptions;
10549                }
10550                return null;
10551            }
10552        } finally {
10553            Binder.restoreCallingIdentity(origId);
10554        }
10555    }
10556
10557    @Override
10558    public void setImmersive(IBinder token, boolean immersive) {
10559        synchronized(this) {
10560            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10561            if (r == null) {
10562                throw new IllegalArgumentException();
10563            }
10564            r.immersive = immersive;
10565
10566            // update associated state if we're frontmost
10567            if (r == mFocusedActivity) {
10568                if (DEBUG_IMMERSIVE) {
10569                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10570                }
10571                applyUpdateLockStateLocked(r);
10572            }
10573        }
10574    }
10575
10576    @Override
10577    public boolean isImmersive(IBinder token) {
10578        synchronized (this) {
10579            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10580            if (r == null) {
10581                throw new IllegalArgumentException();
10582            }
10583            return r.immersive;
10584        }
10585    }
10586
10587    public boolean isTopActivityImmersive() {
10588        enforceNotIsolatedCaller("startActivity");
10589        synchronized (this) {
10590            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10591            return (r != null) ? r.immersive : false;
10592        }
10593    }
10594
10595    @Override
10596    public boolean isTopOfTask(IBinder token) {
10597        synchronized (this) {
10598            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10599            if (r == null) {
10600                throw new IllegalArgumentException();
10601            }
10602            return r.task.getTopActivity() == r;
10603        }
10604    }
10605
10606    public final void enterSafeMode() {
10607        synchronized(this) {
10608            // It only makes sense to do this before the system is ready
10609            // and started launching other packages.
10610            if (!mSystemReady) {
10611                try {
10612                    AppGlobals.getPackageManager().enterSafeMode();
10613                } catch (RemoteException e) {
10614                }
10615            }
10616
10617            mSafeMode = true;
10618        }
10619    }
10620
10621    public final void showSafeModeOverlay() {
10622        View v = LayoutInflater.from(mContext).inflate(
10623                com.android.internal.R.layout.safe_mode, null);
10624        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10625        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10626        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10627        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10628        lp.gravity = Gravity.BOTTOM | Gravity.START;
10629        lp.format = v.getBackground().getOpacity();
10630        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10631                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10632        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10633        ((WindowManager)mContext.getSystemService(
10634                Context.WINDOW_SERVICE)).addView(v, lp);
10635    }
10636
10637    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10638        if (!(sender instanceof PendingIntentRecord)) {
10639            return;
10640        }
10641        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10642        synchronized (stats) {
10643            if (mBatteryStatsService.isOnBattery()) {
10644                mBatteryStatsService.enforceCallingPermission();
10645                PendingIntentRecord rec = (PendingIntentRecord)sender;
10646                int MY_UID = Binder.getCallingUid();
10647                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10648                BatteryStatsImpl.Uid.Pkg pkg =
10649                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10650                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10651                pkg.incWakeupsLocked();
10652            }
10653        }
10654    }
10655
10656    public boolean killPids(int[] pids, String pReason, boolean secure) {
10657        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10658            throw new SecurityException("killPids only available to the system");
10659        }
10660        String reason = (pReason == null) ? "Unknown" : pReason;
10661        // XXX Note: don't acquire main activity lock here, because the window
10662        // manager calls in with its locks held.
10663
10664        boolean killed = false;
10665        synchronized (mPidsSelfLocked) {
10666            int[] types = new int[pids.length];
10667            int worstType = 0;
10668            for (int i=0; i<pids.length; i++) {
10669                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10670                if (proc != null) {
10671                    int type = proc.setAdj;
10672                    types[i] = type;
10673                    if (type > worstType) {
10674                        worstType = type;
10675                    }
10676                }
10677            }
10678
10679            // If the worst oom_adj is somewhere in the cached proc LRU range,
10680            // then constrain it so we will kill all cached procs.
10681            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10682                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10683                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10684            }
10685
10686            // If this is not a secure call, don't let it kill processes that
10687            // are important.
10688            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10689                worstType = ProcessList.SERVICE_ADJ;
10690            }
10691
10692            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10693            for (int i=0; i<pids.length; i++) {
10694                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10695                if (proc == null) {
10696                    continue;
10697                }
10698                int adj = proc.setAdj;
10699                if (adj >= worstType && !proc.killedByAm) {
10700                    proc.kill(reason, true);
10701                    killed = true;
10702                }
10703            }
10704        }
10705        return killed;
10706    }
10707
10708    @Override
10709    public void killUid(int uid, String reason) {
10710        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10711            throw new SecurityException("killUid only available to the system");
10712        }
10713        synchronized (this) {
10714            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10715                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10716                    reason != null ? reason : "kill uid");
10717        }
10718    }
10719
10720    @Override
10721    public boolean killProcessesBelowForeground(String reason) {
10722        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10723            throw new SecurityException("killProcessesBelowForeground() only available to system");
10724        }
10725
10726        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10727    }
10728
10729    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10730        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10731            throw new SecurityException("killProcessesBelowAdj() only available to system");
10732        }
10733
10734        boolean killed = false;
10735        synchronized (mPidsSelfLocked) {
10736            final int size = mPidsSelfLocked.size();
10737            for (int i = 0; i < size; i++) {
10738                final int pid = mPidsSelfLocked.keyAt(i);
10739                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10740                if (proc == null) continue;
10741
10742                final int adj = proc.setAdj;
10743                if (adj > belowAdj && !proc.killedByAm) {
10744                    proc.kill(reason, true);
10745                    killed = true;
10746                }
10747            }
10748        }
10749        return killed;
10750    }
10751
10752    @Override
10753    public void hang(final IBinder who, boolean allowRestart) {
10754        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10755                != PackageManager.PERMISSION_GRANTED) {
10756            throw new SecurityException("Requires permission "
10757                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10758        }
10759
10760        final IBinder.DeathRecipient death = new DeathRecipient() {
10761            @Override
10762            public void binderDied() {
10763                synchronized (this) {
10764                    notifyAll();
10765                }
10766            }
10767        };
10768
10769        try {
10770            who.linkToDeath(death, 0);
10771        } catch (RemoteException e) {
10772            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10773            return;
10774        }
10775
10776        synchronized (this) {
10777            Watchdog.getInstance().setAllowRestart(allowRestart);
10778            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10779            synchronized (death) {
10780                while (who.isBinderAlive()) {
10781                    try {
10782                        death.wait();
10783                    } catch (InterruptedException e) {
10784                    }
10785                }
10786            }
10787            Watchdog.getInstance().setAllowRestart(true);
10788        }
10789    }
10790
10791    @Override
10792    public void restart() {
10793        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10794                != PackageManager.PERMISSION_GRANTED) {
10795            throw new SecurityException("Requires permission "
10796                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10797        }
10798
10799        Log.i(TAG, "Sending shutdown broadcast...");
10800
10801        BroadcastReceiver br = new BroadcastReceiver() {
10802            @Override public void onReceive(Context context, Intent intent) {
10803                // Now the broadcast is done, finish up the low-level shutdown.
10804                Log.i(TAG, "Shutting down activity manager...");
10805                shutdown(10000);
10806                Log.i(TAG, "Shutdown complete, restarting!");
10807                Process.killProcess(Process.myPid());
10808                System.exit(10);
10809            }
10810        };
10811
10812        // First send the high-level shut down broadcast.
10813        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10814        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10815        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10816        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10817        mContext.sendOrderedBroadcastAsUser(intent,
10818                UserHandle.ALL, null, br, mHandler, 0, null, null);
10819        */
10820        br.onReceive(mContext, intent);
10821    }
10822
10823    private long getLowRamTimeSinceIdle(long now) {
10824        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10825    }
10826
10827    @Override
10828    public void performIdleMaintenance() {
10829        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10830                != PackageManager.PERMISSION_GRANTED) {
10831            throw new SecurityException("Requires permission "
10832                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10833        }
10834
10835        synchronized (this) {
10836            final long now = SystemClock.uptimeMillis();
10837            final long timeSinceLastIdle = now - mLastIdleTime;
10838            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10839            mLastIdleTime = now;
10840            mLowRamTimeSinceLastIdle = 0;
10841            if (mLowRamStartTime != 0) {
10842                mLowRamStartTime = now;
10843            }
10844
10845            StringBuilder sb = new StringBuilder(128);
10846            sb.append("Idle maintenance over ");
10847            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10848            sb.append(" low RAM for ");
10849            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10850            Slog.i(TAG, sb.toString());
10851
10852            // If at least 1/3 of our time since the last idle period has been spent
10853            // with RAM low, then we want to kill processes.
10854            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10855
10856            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10857                ProcessRecord proc = mLruProcesses.get(i);
10858                if (proc.notCachedSinceIdle) {
10859                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10860                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10861                        if (doKilling && proc.initialIdlePss != 0
10862                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10863                            proc.kill("idle maint (pss " + proc.lastPss
10864                                    + " from " + proc.initialIdlePss + ")", true);
10865                        }
10866                    }
10867                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10868                    proc.notCachedSinceIdle = true;
10869                    proc.initialIdlePss = 0;
10870                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10871                            isSleeping(), now);
10872                }
10873            }
10874
10875            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10876            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10877        }
10878    }
10879
10880    private void retrieveSettings() {
10881        final ContentResolver resolver = mContext.getContentResolver();
10882        String debugApp = Settings.Global.getString(
10883            resolver, Settings.Global.DEBUG_APP);
10884        boolean waitForDebugger = Settings.Global.getInt(
10885            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10886        boolean alwaysFinishActivities = Settings.Global.getInt(
10887            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10888        boolean forceRtl = Settings.Global.getInt(
10889                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10890        // Transfer any global setting for forcing RTL layout, into a System Property
10891        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10892
10893        Configuration configuration = new Configuration();
10894        Settings.System.getConfiguration(resolver, configuration);
10895        if (forceRtl) {
10896            // This will take care of setting the correct layout direction flags
10897            configuration.setLayoutDirection(configuration.locale);
10898        }
10899
10900        synchronized (this) {
10901            mDebugApp = mOrigDebugApp = debugApp;
10902            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10903            mAlwaysFinishActivities = alwaysFinishActivities;
10904            // This happens before any activities are started, so we can
10905            // change mConfiguration in-place.
10906            updateConfigurationLocked(configuration, null, false, true);
10907            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10908        }
10909    }
10910
10911    /** Loads resources after the current configuration has been set. */
10912    private void loadResourcesOnSystemReady() {
10913        final Resources res = mContext.getResources();
10914        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10915        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10916        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10917    }
10918
10919    public boolean testIsSystemReady() {
10920        // no need to synchronize(this) just to read & return the value
10921        return mSystemReady;
10922    }
10923
10924    private static File getCalledPreBootReceiversFile() {
10925        File dataDir = Environment.getDataDirectory();
10926        File systemDir = new File(dataDir, "system");
10927        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10928        return fname;
10929    }
10930
10931    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10932        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10933        File file = getCalledPreBootReceiversFile();
10934        FileInputStream fis = null;
10935        try {
10936            fis = new FileInputStream(file);
10937            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10938            int fvers = dis.readInt();
10939            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10940                String vers = dis.readUTF();
10941                String codename = dis.readUTF();
10942                String build = dis.readUTF();
10943                if (android.os.Build.VERSION.RELEASE.equals(vers)
10944                        && android.os.Build.VERSION.CODENAME.equals(codename)
10945                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10946                    int num = dis.readInt();
10947                    while (num > 0) {
10948                        num--;
10949                        String pkg = dis.readUTF();
10950                        String cls = dis.readUTF();
10951                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10952                    }
10953                }
10954            }
10955        } catch (FileNotFoundException e) {
10956        } catch (IOException e) {
10957            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10958        } finally {
10959            if (fis != null) {
10960                try {
10961                    fis.close();
10962                } catch (IOException e) {
10963                }
10964            }
10965        }
10966        return lastDoneReceivers;
10967    }
10968
10969    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10970        File file = getCalledPreBootReceiversFile();
10971        FileOutputStream fos = null;
10972        DataOutputStream dos = null;
10973        try {
10974            fos = new FileOutputStream(file);
10975            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10976            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10977            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10978            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10979            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10980            dos.writeInt(list.size());
10981            for (int i=0; i<list.size(); i++) {
10982                dos.writeUTF(list.get(i).getPackageName());
10983                dos.writeUTF(list.get(i).getClassName());
10984            }
10985        } catch (IOException e) {
10986            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10987            file.delete();
10988        } finally {
10989            FileUtils.sync(fos);
10990            if (dos != null) {
10991                try {
10992                    dos.close();
10993                } catch (IOException e) {
10994                    // TODO Auto-generated catch block
10995                    e.printStackTrace();
10996                }
10997            }
10998        }
10999    }
11000
11001    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11002            ArrayList<ComponentName> doneReceivers, int userId) {
11003        boolean waitingUpdate = false;
11004        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11005        List<ResolveInfo> ris = null;
11006        try {
11007            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11008                    intent, null, 0, userId);
11009        } catch (RemoteException e) {
11010        }
11011        if (ris != null) {
11012            for (int i=ris.size()-1; i>=0; i--) {
11013                if ((ris.get(i).activityInfo.applicationInfo.flags
11014                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11015                    ris.remove(i);
11016                }
11017            }
11018            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11019
11020            // For User 0, load the version number. When delivering to a new user, deliver
11021            // to all receivers.
11022            if (userId == UserHandle.USER_OWNER) {
11023                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11024                for (int i=0; i<ris.size(); i++) {
11025                    ActivityInfo ai = ris.get(i).activityInfo;
11026                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11027                    if (lastDoneReceivers.contains(comp)) {
11028                        // We already did the pre boot receiver for this app with the current
11029                        // platform version, so don't do it again...
11030                        ris.remove(i);
11031                        i--;
11032                        // ...however, do keep it as one that has been done, so we don't
11033                        // forget about it when rewriting the file of last done receivers.
11034                        doneReceivers.add(comp);
11035                    }
11036                }
11037            }
11038
11039            // If primary user, send broadcast to all available users, else just to userId
11040            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11041                    : new int[] { userId };
11042            for (int i = 0; i < ris.size(); i++) {
11043                ActivityInfo ai = ris.get(i).activityInfo;
11044                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11045                doneReceivers.add(comp);
11046                intent.setComponent(comp);
11047                for (int j=0; j<users.length; j++) {
11048                    IIntentReceiver finisher = null;
11049                    // On last receiver and user, set up a completion callback
11050                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11051                        finisher = new IIntentReceiver.Stub() {
11052                            public void performReceive(Intent intent, int resultCode,
11053                                    String data, Bundle extras, boolean ordered,
11054                                    boolean sticky, int sendingUser) {
11055                                // The raw IIntentReceiver interface is called
11056                                // with the AM lock held, so redispatch to
11057                                // execute our code without the lock.
11058                                mHandler.post(onFinishCallback);
11059                            }
11060                        };
11061                    }
11062                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11063                            + " for user " + users[j]);
11064                    broadcastIntentLocked(null, null, intent, null, finisher,
11065                            0, null, null, null, AppOpsManager.OP_NONE,
11066                            true, false, MY_PID, Process.SYSTEM_UID,
11067                            users[j]);
11068                    if (finisher != null) {
11069                        waitingUpdate = true;
11070                    }
11071                }
11072            }
11073        }
11074
11075        return waitingUpdate;
11076    }
11077
11078    public void systemReady(final Runnable goingCallback) {
11079        synchronized(this) {
11080            if (mSystemReady) {
11081                // If we're done calling all the receivers, run the next "boot phase" passed in
11082                // by the SystemServer
11083                if (goingCallback != null) {
11084                    goingCallback.run();
11085                }
11086                return;
11087            }
11088
11089            // Make sure we have the current profile info, since it is needed for
11090            // security checks.
11091            updateCurrentProfileIdsLocked();
11092
11093            if (mRecentTasks == null) {
11094                mRecentTasks = mTaskPersister.restoreTasksLocked();
11095                if (!mRecentTasks.isEmpty()) {
11096                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11097                }
11098                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11099                mTaskPersister.startPersisting();
11100            }
11101
11102            // Check to see if there are any update receivers to run.
11103            if (!mDidUpdate) {
11104                if (mWaitingUpdate) {
11105                    return;
11106                }
11107                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11108                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11109                    public void run() {
11110                        synchronized (ActivityManagerService.this) {
11111                            mDidUpdate = true;
11112                        }
11113                        writeLastDonePreBootReceivers(doneReceivers);
11114                        showBootMessage(mContext.getText(
11115                                R.string.android_upgrading_complete),
11116                                false);
11117                        systemReady(goingCallback);
11118                    }
11119                }, doneReceivers, UserHandle.USER_OWNER);
11120
11121                if (mWaitingUpdate) {
11122                    return;
11123                }
11124                mDidUpdate = true;
11125            }
11126
11127            mAppOpsService.systemReady();
11128            mSystemReady = true;
11129        }
11130
11131        ArrayList<ProcessRecord> procsToKill = null;
11132        synchronized(mPidsSelfLocked) {
11133            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11134                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11135                if (!isAllowedWhileBooting(proc.info)){
11136                    if (procsToKill == null) {
11137                        procsToKill = new ArrayList<ProcessRecord>();
11138                    }
11139                    procsToKill.add(proc);
11140                }
11141            }
11142        }
11143
11144        synchronized(this) {
11145            if (procsToKill != null) {
11146                for (int i=procsToKill.size()-1; i>=0; i--) {
11147                    ProcessRecord proc = procsToKill.get(i);
11148                    Slog.i(TAG, "Removing system update proc: " + proc);
11149                    removeProcessLocked(proc, true, false, "system update done");
11150                }
11151            }
11152
11153            // Now that we have cleaned up any update processes, we
11154            // are ready to start launching real processes and know that
11155            // we won't trample on them any more.
11156            mProcessesReady = true;
11157        }
11158
11159        Slog.i(TAG, "System now ready");
11160        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11161            SystemClock.uptimeMillis());
11162
11163        synchronized(this) {
11164            // Make sure we have no pre-ready processes sitting around.
11165
11166            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11167                ResolveInfo ri = mContext.getPackageManager()
11168                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11169                                STOCK_PM_FLAGS);
11170                CharSequence errorMsg = null;
11171                if (ri != null) {
11172                    ActivityInfo ai = ri.activityInfo;
11173                    ApplicationInfo app = ai.applicationInfo;
11174                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11175                        mTopAction = Intent.ACTION_FACTORY_TEST;
11176                        mTopData = null;
11177                        mTopComponent = new ComponentName(app.packageName,
11178                                ai.name);
11179                    } else {
11180                        errorMsg = mContext.getResources().getText(
11181                                com.android.internal.R.string.factorytest_not_system);
11182                    }
11183                } else {
11184                    errorMsg = mContext.getResources().getText(
11185                            com.android.internal.R.string.factorytest_no_action);
11186                }
11187                if (errorMsg != null) {
11188                    mTopAction = null;
11189                    mTopData = null;
11190                    mTopComponent = null;
11191                    Message msg = Message.obtain();
11192                    msg.what = SHOW_FACTORY_ERROR_MSG;
11193                    msg.getData().putCharSequence("msg", errorMsg);
11194                    mHandler.sendMessage(msg);
11195                }
11196            }
11197        }
11198
11199        retrieveSettings();
11200        loadResourcesOnSystemReady();
11201
11202        synchronized (this) {
11203            readGrantedUriPermissionsLocked();
11204        }
11205
11206        if (goingCallback != null) goingCallback.run();
11207
11208        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11209                Integer.toString(mCurrentUserId), mCurrentUserId);
11210        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11211                Integer.toString(mCurrentUserId), mCurrentUserId);
11212        mSystemServiceManager.startUser(mCurrentUserId);
11213
11214        synchronized (this) {
11215            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11216                try {
11217                    List apps = AppGlobals.getPackageManager().
11218                        getPersistentApplications(STOCK_PM_FLAGS);
11219                    if (apps != null) {
11220                        int N = apps.size();
11221                        int i;
11222                        for (i=0; i<N; i++) {
11223                            ApplicationInfo info
11224                                = (ApplicationInfo)apps.get(i);
11225                            if (info != null &&
11226                                    !info.packageName.equals("android")) {
11227                                addAppLocked(info, false, null /* ABI override */);
11228                            }
11229                        }
11230                    }
11231                } catch (RemoteException ex) {
11232                    // pm is in same process, this will never happen.
11233                }
11234            }
11235
11236            // Start up initial activity.
11237            mBooting = true;
11238            startHomeActivityLocked(mCurrentUserId);
11239
11240            try {
11241                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11242                    Message msg = Message.obtain();
11243                    msg.what = SHOW_UID_ERROR_MSG;
11244                    mHandler.sendMessage(msg);
11245                }
11246            } catch (RemoteException e) {
11247            }
11248
11249            long ident = Binder.clearCallingIdentity();
11250            try {
11251                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11252                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11253                        | Intent.FLAG_RECEIVER_FOREGROUND);
11254                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11255                broadcastIntentLocked(null, null, intent,
11256                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11257                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11258                intent = new Intent(Intent.ACTION_USER_STARTING);
11259                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11260                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11261                broadcastIntentLocked(null, null, intent,
11262                        null, new IIntentReceiver.Stub() {
11263                            @Override
11264                            public void performReceive(Intent intent, int resultCode, String data,
11265                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11266                                    throws RemoteException {
11267                            }
11268                        }, 0, null, null,
11269                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11270                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11271            } catch (Throwable t) {
11272                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11273            } finally {
11274                Binder.restoreCallingIdentity(ident);
11275            }
11276            mStackSupervisor.resumeTopActivitiesLocked();
11277            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11278        }
11279    }
11280
11281    private boolean makeAppCrashingLocked(ProcessRecord app,
11282            String shortMsg, String longMsg, String stackTrace) {
11283        app.crashing = true;
11284        app.crashingReport = generateProcessError(app,
11285                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11286        startAppProblemLocked(app);
11287        app.stopFreezingAllLocked();
11288        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11289    }
11290
11291    private void makeAppNotRespondingLocked(ProcessRecord app,
11292            String activity, String shortMsg, String longMsg) {
11293        app.notResponding = true;
11294        app.notRespondingReport = generateProcessError(app,
11295                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11296                activity, shortMsg, longMsg, null);
11297        startAppProblemLocked(app);
11298        app.stopFreezingAllLocked();
11299    }
11300
11301    /**
11302     * Generate a process error record, suitable for attachment to a ProcessRecord.
11303     *
11304     * @param app The ProcessRecord in which the error occurred.
11305     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11306     *                      ActivityManager.AppErrorStateInfo
11307     * @param activity The activity associated with the crash, if known.
11308     * @param shortMsg Short message describing the crash.
11309     * @param longMsg Long message describing the crash.
11310     * @param stackTrace Full crash stack trace, may be null.
11311     *
11312     * @return Returns a fully-formed AppErrorStateInfo record.
11313     */
11314    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11315            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11316        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11317
11318        report.condition = condition;
11319        report.processName = app.processName;
11320        report.pid = app.pid;
11321        report.uid = app.info.uid;
11322        report.tag = activity;
11323        report.shortMsg = shortMsg;
11324        report.longMsg = longMsg;
11325        report.stackTrace = stackTrace;
11326
11327        return report;
11328    }
11329
11330    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11331        synchronized (this) {
11332            app.crashing = false;
11333            app.crashingReport = null;
11334            app.notResponding = false;
11335            app.notRespondingReport = null;
11336            if (app.anrDialog == fromDialog) {
11337                app.anrDialog = null;
11338            }
11339            if (app.waitDialog == fromDialog) {
11340                app.waitDialog = null;
11341            }
11342            if (app.pid > 0 && app.pid != MY_PID) {
11343                handleAppCrashLocked(app, null, null, null);
11344                app.kill("user request after error", true);
11345            }
11346        }
11347    }
11348
11349    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11350            String stackTrace) {
11351        long now = SystemClock.uptimeMillis();
11352
11353        Long crashTime;
11354        if (!app.isolated) {
11355            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11356        } else {
11357            crashTime = null;
11358        }
11359        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11360            // This process loses!
11361            Slog.w(TAG, "Process " + app.info.processName
11362                    + " has crashed too many times: killing!");
11363            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11364                    app.userId, app.info.processName, app.uid);
11365            mStackSupervisor.handleAppCrashLocked(app);
11366            if (!app.persistent) {
11367                // We don't want to start this process again until the user
11368                // explicitly does so...  but for persistent process, we really
11369                // need to keep it running.  If a persistent process is actually
11370                // repeatedly crashing, then badness for everyone.
11371                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11372                        app.info.processName);
11373                if (!app.isolated) {
11374                    // XXX We don't have a way to mark isolated processes
11375                    // as bad, since they don't have a peristent identity.
11376                    mBadProcesses.put(app.info.processName, app.uid,
11377                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11378                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11379                }
11380                app.bad = true;
11381                app.removed = true;
11382                // Don't let services in this process be restarted and potentially
11383                // annoy the user repeatedly.  Unless it is persistent, since those
11384                // processes run critical code.
11385                removeProcessLocked(app, false, false, "crash");
11386                mStackSupervisor.resumeTopActivitiesLocked();
11387                return false;
11388            }
11389            mStackSupervisor.resumeTopActivitiesLocked();
11390        } else {
11391            mStackSupervisor.finishTopRunningActivityLocked(app);
11392        }
11393
11394        // Bump up the crash count of any services currently running in the proc.
11395        for (int i=app.services.size()-1; i>=0; i--) {
11396            // Any services running in the application need to be placed
11397            // back in the pending list.
11398            ServiceRecord sr = app.services.valueAt(i);
11399            sr.crashCount++;
11400        }
11401
11402        // If the crashing process is what we consider to be the "home process" and it has been
11403        // replaced by a third-party app, clear the package preferred activities from packages
11404        // with a home activity running in the process to prevent a repeatedly crashing app
11405        // from blocking the user to manually clear the list.
11406        final ArrayList<ActivityRecord> activities = app.activities;
11407        if (app == mHomeProcess && activities.size() > 0
11408                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11409            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11410                final ActivityRecord r = activities.get(activityNdx);
11411                if (r.isHomeActivity()) {
11412                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11413                    try {
11414                        ActivityThread.getPackageManager()
11415                                .clearPackagePreferredActivities(r.packageName);
11416                    } catch (RemoteException c) {
11417                        // pm is in same process, this will never happen.
11418                    }
11419                }
11420            }
11421        }
11422
11423        if (!app.isolated) {
11424            // XXX Can't keep track of crash times for isolated processes,
11425            // because they don't have a perisistent identity.
11426            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11427        }
11428
11429        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11430        return true;
11431    }
11432
11433    void startAppProblemLocked(ProcessRecord app) {
11434        // If this app is not running under the current user, then we
11435        // can't give it a report button because that would require
11436        // launching the report UI under a different user.
11437        app.errorReportReceiver = null;
11438
11439        for (int userId : mCurrentProfileIds) {
11440            if (app.userId == userId) {
11441                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11442                        mContext, app.info.packageName, app.info.flags);
11443            }
11444        }
11445        skipCurrentReceiverLocked(app);
11446    }
11447
11448    void skipCurrentReceiverLocked(ProcessRecord app) {
11449        for (BroadcastQueue queue : mBroadcastQueues) {
11450            queue.skipCurrentReceiverLocked(app);
11451        }
11452    }
11453
11454    /**
11455     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11456     * The application process will exit immediately after this call returns.
11457     * @param app object of the crashing app, null for the system server
11458     * @param crashInfo describing the exception
11459     */
11460    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11461        ProcessRecord r = findAppProcess(app, "Crash");
11462        final String processName = app == null ? "system_server"
11463                : (r == null ? "unknown" : r.processName);
11464
11465        handleApplicationCrashInner("crash", r, processName, crashInfo);
11466    }
11467
11468    /* Native crash reporting uses this inner version because it needs to be somewhat
11469     * decoupled from the AM-managed cleanup lifecycle
11470     */
11471    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11472            ApplicationErrorReport.CrashInfo crashInfo) {
11473        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11474                UserHandle.getUserId(Binder.getCallingUid()), processName,
11475                r == null ? -1 : r.info.flags,
11476                crashInfo.exceptionClassName,
11477                crashInfo.exceptionMessage,
11478                crashInfo.throwFileName,
11479                crashInfo.throwLineNumber);
11480
11481        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11482
11483        crashApplication(r, crashInfo);
11484    }
11485
11486    public void handleApplicationStrictModeViolation(
11487            IBinder app,
11488            int violationMask,
11489            StrictMode.ViolationInfo info) {
11490        ProcessRecord r = findAppProcess(app, "StrictMode");
11491        if (r == null) {
11492            return;
11493        }
11494
11495        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11496            Integer stackFingerprint = info.hashCode();
11497            boolean logIt = true;
11498            synchronized (mAlreadyLoggedViolatedStacks) {
11499                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11500                    logIt = false;
11501                    // TODO: sub-sample into EventLog for these, with
11502                    // the info.durationMillis?  Then we'd get
11503                    // the relative pain numbers, without logging all
11504                    // the stack traces repeatedly.  We'd want to do
11505                    // likewise in the client code, which also does
11506                    // dup suppression, before the Binder call.
11507                } else {
11508                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11509                        mAlreadyLoggedViolatedStacks.clear();
11510                    }
11511                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11512                }
11513            }
11514            if (logIt) {
11515                logStrictModeViolationToDropBox(r, info);
11516            }
11517        }
11518
11519        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11520            AppErrorResult result = new AppErrorResult();
11521            synchronized (this) {
11522                final long origId = Binder.clearCallingIdentity();
11523
11524                Message msg = Message.obtain();
11525                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11526                HashMap<String, Object> data = new HashMap<String, Object>();
11527                data.put("result", result);
11528                data.put("app", r);
11529                data.put("violationMask", violationMask);
11530                data.put("info", info);
11531                msg.obj = data;
11532                mHandler.sendMessage(msg);
11533
11534                Binder.restoreCallingIdentity(origId);
11535            }
11536            int res = result.get();
11537            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11538        }
11539    }
11540
11541    // Depending on the policy in effect, there could be a bunch of
11542    // these in quick succession so we try to batch these together to
11543    // minimize disk writes, number of dropbox entries, and maximize
11544    // compression, by having more fewer, larger records.
11545    private void logStrictModeViolationToDropBox(
11546            ProcessRecord process,
11547            StrictMode.ViolationInfo info) {
11548        if (info == null) {
11549            return;
11550        }
11551        final boolean isSystemApp = process == null ||
11552                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11553                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11554        final String processName = process == null ? "unknown" : process.processName;
11555        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11556        final DropBoxManager dbox = (DropBoxManager)
11557                mContext.getSystemService(Context.DROPBOX_SERVICE);
11558
11559        // Exit early if the dropbox isn't configured to accept this report type.
11560        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11561
11562        boolean bufferWasEmpty;
11563        boolean needsFlush;
11564        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11565        synchronized (sb) {
11566            bufferWasEmpty = sb.length() == 0;
11567            appendDropBoxProcessHeaders(process, processName, sb);
11568            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11569            sb.append("System-App: ").append(isSystemApp).append("\n");
11570            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11571            if (info.violationNumThisLoop != 0) {
11572                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11573            }
11574            if (info.numAnimationsRunning != 0) {
11575                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11576            }
11577            if (info.broadcastIntentAction != null) {
11578                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11579            }
11580            if (info.durationMillis != -1) {
11581                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11582            }
11583            if (info.numInstances != -1) {
11584                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11585            }
11586            if (info.tags != null) {
11587                for (String tag : info.tags) {
11588                    sb.append("Span-Tag: ").append(tag).append("\n");
11589                }
11590            }
11591            sb.append("\n");
11592            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11593                sb.append(info.crashInfo.stackTrace);
11594            }
11595            sb.append("\n");
11596
11597            // Only buffer up to ~64k.  Various logging bits truncate
11598            // things at 128k.
11599            needsFlush = (sb.length() > 64 * 1024);
11600        }
11601
11602        // Flush immediately if the buffer's grown too large, or this
11603        // is a non-system app.  Non-system apps are isolated with a
11604        // different tag & policy and not batched.
11605        //
11606        // Batching is useful during internal testing with
11607        // StrictMode settings turned up high.  Without batching,
11608        // thousands of separate files could be created on boot.
11609        if (!isSystemApp || needsFlush) {
11610            new Thread("Error dump: " + dropboxTag) {
11611                @Override
11612                public void run() {
11613                    String report;
11614                    synchronized (sb) {
11615                        report = sb.toString();
11616                        sb.delete(0, sb.length());
11617                        sb.trimToSize();
11618                    }
11619                    if (report.length() != 0) {
11620                        dbox.addText(dropboxTag, report);
11621                    }
11622                }
11623            }.start();
11624            return;
11625        }
11626
11627        // System app batching:
11628        if (!bufferWasEmpty) {
11629            // An existing dropbox-writing thread is outstanding, so
11630            // we don't need to start it up.  The existing thread will
11631            // catch the buffer appends we just did.
11632            return;
11633        }
11634
11635        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11636        // (After this point, we shouldn't access AMS internal data structures.)
11637        new Thread("Error dump: " + dropboxTag) {
11638            @Override
11639            public void run() {
11640                // 5 second sleep to let stacks arrive and be batched together
11641                try {
11642                    Thread.sleep(5000);  // 5 seconds
11643                } catch (InterruptedException e) {}
11644
11645                String errorReport;
11646                synchronized (mStrictModeBuffer) {
11647                    errorReport = mStrictModeBuffer.toString();
11648                    if (errorReport.length() == 0) {
11649                        return;
11650                    }
11651                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11652                    mStrictModeBuffer.trimToSize();
11653                }
11654                dbox.addText(dropboxTag, errorReport);
11655            }
11656        }.start();
11657    }
11658
11659    /**
11660     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11661     * @param app object of the crashing app, null for the system server
11662     * @param tag reported by the caller
11663     * @param system whether this wtf is coming from the system
11664     * @param crashInfo describing the context of the error
11665     * @return true if the process should exit immediately (WTF is fatal)
11666     */
11667    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11668            final ApplicationErrorReport.CrashInfo crashInfo) {
11669        final int callingUid = Binder.getCallingUid();
11670        final int callingPid = Binder.getCallingPid();
11671
11672        if (system) {
11673            // If this is coming from the system, we could very well have low-level
11674            // system locks held, so we want to do this all asynchronously.  And we
11675            // never want this to become fatal, so there is that too.
11676            mHandler.post(new Runnable() {
11677                @Override public void run() {
11678                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11679                }
11680            });
11681            return false;
11682        }
11683
11684        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11685                crashInfo);
11686
11687        if (r != null && r.pid != Process.myPid() &&
11688                Settings.Global.getInt(mContext.getContentResolver(),
11689                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11690            crashApplication(r, crashInfo);
11691            return true;
11692        } else {
11693            return false;
11694        }
11695    }
11696
11697    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11698            final ApplicationErrorReport.CrashInfo crashInfo) {
11699        final ProcessRecord r = findAppProcess(app, "WTF");
11700        final String processName = app == null ? "system_server"
11701                : (r == null ? "unknown" : r.processName);
11702
11703        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11704                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11705
11706        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11707
11708        return r;
11709    }
11710
11711    /**
11712     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11713     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11714     */
11715    private ProcessRecord findAppProcess(IBinder app, String reason) {
11716        if (app == null) {
11717            return null;
11718        }
11719
11720        synchronized (this) {
11721            final int NP = mProcessNames.getMap().size();
11722            for (int ip=0; ip<NP; ip++) {
11723                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11724                final int NA = apps.size();
11725                for (int ia=0; ia<NA; ia++) {
11726                    ProcessRecord p = apps.valueAt(ia);
11727                    if (p.thread != null && p.thread.asBinder() == app) {
11728                        return p;
11729                    }
11730                }
11731            }
11732
11733            Slog.w(TAG, "Can't find mystery application for " + reason
11734                    + " from pid=" + Binder.getCallingPid()
11735                    + " uid=" + Binder.getCallingUid() + ": " + app);
11736            return null;
11737        }
11738    }
11739
11740    /**
11741     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11742     * to append various headers to the dropbox log text.
11743     */
11744    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11745            StringBuilder sb) {
11746        // Watchdog thread ends up invoking this function (with
11747        // a null ProcessRecord) to add the stack file to dropbox.
11748        // Do not acquire a lock on this (am) in such cases, as it
11749        // could cause a potential deadlock, if and when watchdog
11750        // is invoked due to unavailability of lock on am and it
11751        // would prevent watchdog from killing system_server.
11752        if (process == null) {
11753            sb.append("Process: ").append(processName).append("\n");
11754            return;
11755        }
11756        // Note: ProcessRecord 'process' is guarded by the service
11757        // instance.  (notably process.pkgList, which could otherwise change
11758        // concurrently during execution of this method)
11759        synchronized (this) {
11760            sb.append("Process: ").append(processName).append("\n");
11761            int flags = process.info.flags;
11762            IPackageManager pm = AppGlobals.getPackageManager();
11763            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11764            for (int ip=0; ip<process.pkgList.size(); ip++) {
11765                String pkg = process.pkgList.keyAt(ip);
11766                sb.append("Package: ").append(pkg);
11767                try {
11768                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11769                    if (pi != null) {
11770                        sb.append(" v").append(pi.versionCode);
11771                        if (pi.versionName != null) {
11772                            sb.append(" (").append(pi.versionName).append(")");
11773                        }
11774                    }
11775                } catch (RemoteException e) {
11776                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11777                }
11778                sb.append("\n");
11779            }
11780        }
11781    }
11782
11783    private static String processClass(ProcessRecord process) {
11784        if (process == null || process.pid == MY_PID) {
11785            return "system_server";
11786        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11787            return "system_app";
11788        } else {
11789            return "data_app";
11790        }
11791    }
11792
11793    /**
11794     * Write a description of an error (crash, WTF, ANR) to the drop box.
11795     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11796     * @param process which caused the error, null means the system server
11797     * @param activity which triggered the error, null if unknown
11798     * @param parent activity related to the error, null if unknown
11799     * @param subject line related to the error, null if absent
11800     * @param report in long form describing the error, null if absent
11801     * @param logFile to include in the report, null if none
11802     * @param crashInfo giving an application stack trace, null if absent
11803     */
11804    public void addErrorToDropBox(String eventType,
11805            ProcessRecord process, String processName, ActivityRecord activity,
11806            ActivityRecord parent, String subject,
11807            final String report, final File logFile,
11808            final ApplicationErrorReport.CrashInfo crashInfo) {
11809        // NOTE -- this must never acquire the ActivityManagerService lock,
11810        // otherwise the watchdog may be prevented from resetting the system.
11811
11812        final String dropboxTag = processClass(process) + "_" + eventType;
11813        final DropBoxManager dbox = (DropBoxManager)
11814                mContext.getSystemService(Context.DROPBOX_SERVICE);
11815
11816        // Exit early if the dropbox isn't configured to accept this report type.
11817        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11818
11819        final StringBuilder sb = new StringBuilder(1024);
11820        appendDropBoxProcessHeaders(process, processName, sb);
11821        if (activity != null) {
11822            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11823        }
11824        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11825            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11826        }
11827        if (parent != null && parent != activity) {
11828            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11829        }
11830        if (subject != null) {
11831            sb.append("Subject: ").append(subject).append("\n");
11832        }
11833        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11834        if (Debug.isDebuggerConnected()) {
11835            sb.append("Debugger: Connected\n");
11836        }
11837        sb.append("\n");
11838
11839        // Do the rest in a worker thread to avoid blocking the caller on I/O
11840        // (After this point, we shouldn't access AMS internal data structures.)
11841        Thread worker = new Thread("Error dump: " + dropboxTag) {
11842            @Override
11843            public void run() {
11844                if (report != null) {
11845                    sb.append(report);
11846                }
11847                if (logFile != null) {
11848                    try {
11849                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11850                                    "\n\n[[TRUNCATED]]"));
11851                    } catch (IOException e) {
11852                        Slog.e(TAG, "Error reading " + logFile, e);
11853                    }
11854                }
11855                if (crashInfo != null && crashInfo.stackTrace != null) {
11856                    sb.append(crashInfo.stackTrace);
11857                }
11858
11859                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11860                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11861                if (lines > 0) {
11862                    sb.append("\n");
11863
11864                    // Merge several logcat streams, and take the last N lines
11865                    InputStreamReader input = null;
11866                    try {
11867                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11868                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11869                                "-b", "crash",
11870                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11871
11872                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11873                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11874                        input = new InputStreamReader(logcat.getInputStream());
11875
11876                        int num;
11877                        char[] buf = new char[8192];
11878                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11879                    } catch (IOException e) {
11880                        Slog.e(TAG, "Error running logcat", e);
11881                    } finally {
11882                        if (input != null) try { input.close(); } catch (IOException e) {}
11883                    }
11884                }
11885
11886                dbox.addText(dropboxTag, sb.toString());
11887            }
11888        };
11889
11890        if (process == null) {
11891            // If process is null, we are being called from some internal code
11892            // and may be about to die -- run this synchronously.
11893            worker.run();
11894        } else {
11895            worker.start();
11896        }
11897    }
11898
11899    /**
11900     * Bring up the "unexpected error" dialog box for a crashing app.
11901     * Deal with edge cases (intercepts from instrumented applications,
11902     * ActivityController, error intent receivers, that sort of thing).
11903     * @param r the application crashing
11904     * @param crashInfo describing the failure
11905     */
11906    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11907        long timeMillis = System.currentTimeMillis();
11908        String shortMsg = crashInfo.exceptionClassName;
11909        String longMsg = crashInfo.exceptionMessage;
11910        String stackTrace = crashInfo.stackTrace;
11911        if (shortMsg != null && longMsg != null) {
11912            longMsg = shortMsg + ": " + longMsg;
11913        } else if (shortMsg != null) {
11914            longMsg = shortMsg;
11915        }
11916
11917        AppErrorResult result = new AppErrorResult();
11918        synchronized (this) {
11919            if (mController != null) {
11920                try {
11921                    String name = r != null ? r.processName : null;
11922                    int pid = r != null ? r.pid : Binder.getCallingPid();
11923                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11924                    if (!mController.appCrashed(name, pid,
11925                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11926                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11927                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11928                            Slog.w(TAG, "Skip killing native crashed app " + name
11929                                    + "(" + pid + ") during testing");
11930                        } else {
11931                            Slog.w(TAG, "Force-killing crashed app " + name
11932                                    + " at watcher's request");
11933                            if (r != null) {
11934                                r.kill("crash", true);
11935                            } else {
11936                                // Huh.
11937                                Process.killProcess(pid);
11938                                Process.killProcessGroup(uid, pid);
11939                            }
11940                        }
11941                        return;
11942                    }
11943                } catch (RemoteException e) {
11944                    mController = null;
11945                    Watchdog.getInstance().setActivityController(null);
11946                }
11947            }
11948
11949            final long origId = Binder.clearCallingIdentity();
11950
11951            // If this process is running instrumentation, finish it.
11952            if (r != null && r.instrumentationClass != null) {
11953                Slog.w(TAG, "Error in app " + r.processName
11954                      + " running instrumentation " + r.instrumentationClass + ":");
11955                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11956                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11957                Bundle info = new Bundle();
11958                info.putString("shortMsg", shortMsg);
11959                info.putString("longMsg", longMsg);
11960                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11961                Binder.restoreCallingIdentity(origId);
11962                return;
11963            }
11964
11965            // If we can't identify the process or it's already exceeded its crash quota,
11966            // quit right away without showing a crash dialog.
11967            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11968                Binder.restoreCallingIdentity(origId);
11969                return;
11970            }
11971
11972            Message msg = Message.obtain();
11973            msg.what = SHOW_ERROR_MSG;
11974            HashMap data = new HashMap();
11975            data.put("result", result);
11976            data.put("app", r);
11977            msg.obj = data;
11978            mHandler.sendMessage(msg);
11979
11980            Binder.restoreCallingIdentity(origId);
11981        }
11982
11983        int res = result.get();
11984
11985        Intent appErrorIntent = null;
11986        synchronized (this) {
11987            if (r != null && !r.isolated) {
11988                // XXX Can't keep track of crash time for isolated processes,
11989                // since they don't have a persistent identity.
11990                mProcessCrashTimes.put(r.info.processName, r.uid,
11991                        SystemClock.uptimeMillis());
11992            }
11993            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11994                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11995            }
11996        }
11997
11998        if (appErrorIntent != null) {
11999            try {
12000                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12001            } catch (ActivityNotFoundException e) {
12002                Slog.w(TAG, "bug report receiver dissappeared", e);
12003            }
12004        }
12005    }
12006
12007    Intent createAppErrorIntentLocked(ProcessRecord r,
12008            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12009        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12010        if (report == null) {
12011            return null;
12012        }
12013        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12014        result.setComponent(r.errorReportReceiver);
12015        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12016        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12017        return result;
12018    }
12019
12020    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12021            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12022        if (r.errorReportReceiver == null) {
12023            return null;
12024        }
12025
12026        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12027            return null;
12028        }
12029
12030        ApplicationErrorReport report = new ApplicationErrorReport();
12031        report.packageName = r.info.packageName;
12032        report.installerPackageName = r.errorReportReceiver.getPackageName();
12033        report.processName = r.processName;
12034        report.time = timeMillis;
12035        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12036
12037        if (r.crashing || r.forceCrashReport) {
12038            report.type = ApplicationErrorReport.TYPE_CRASH;
12039            report.crashInfo = crashInfo;
12040        } else if (r.notResponding) {
12041            report.type = ApplicationErrorReport.TYPE_ANR;
12042            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12043
12044            report.anrInfo.activity = r.notRespondingReport.tag;
12045            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12046            report.anrInfo.info = r.notRespondingReport.longMsg;
12047        }
12048
12049        return report;
12050    }
12051
12052    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12053        enforceNotIsolatedCaller("getProcessesInErrorState");
12054        // assume our apps are happy - lazy create the list
12055        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12056
12057        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12058                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12059        int userId = UserHandle.getUserId(Binder.getCallingUid());
12060
12061        synchronized (this) {
12062
12063            // iterate across all processes
12064            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12065                ProcessRecord app = mLruProcesses.get(i);
12066                if (!allUsers && app.userId != userId) {
12067                    continue;
12068                }
12069                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12070                    // This one's in trouble, so we'll generate a report for it
12071                    // crashes are higher priority (in case there's a crash *and* an anr)
12072                    ActivityManager.ProcessErrorStateInfo report = null;
12073                    if (app.crashing) {
12074                        report = app.crashingReport;
12075                    } else if (app.notResponding) {
12076                        report = app.notRespondingReport;
12077                    }
12078
12079                    if (report != null) {
12080                        if (errList == null) {
12081                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12082                        }
12083                        errList.add(report);
12084                    } else {
12085                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12086                                " crashing = " + app.crashing +
12087                                " notResponding = " + app.notResponding);
12088                    }
12089                }
12090            }
12091        }
12092
12093        return errList;
12094    }
12095
12096    static int procStateToImportance(int procState, int memAdj,
12097            ActivityManager.RunningAppProcessInfo currApp) {
12098        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12099        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12100            currApp.lru = memAdj;
12101        } else {
12102            currApp.lru = 0;
12103        }
12104        return imp;
12105    }
12106
12107    private void fillInProcMemInfo(ProcessRecord app,
12108            ActivityManager.RunningAppProcessInfo outInfo) {
12109        outInfo.pid = app.pid;
12110        outInfo.uid = app.info.uid;
12111        if (mHeavyWeightProcess == app) {
12112            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12113        }
12114        if (app.persistent) {
12115            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12116        }
12117        if (app.activities.size() > 0) {
12118            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12119        }
12120        outInfo.lastTrimLevel = app.trimMemoryLevel;
12121        int adj = app.curAdj;
12122        int procState = app.curProcState;
12123        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12124        outInfo.importanceReasonCode = app.adjTypeCode;
12125        outInfo.processState = app.curProcState;
12126    }
12127
12128    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12129        enforceNotIsolatedCaller("getRunningAppProcesses");
12130        // Lazy instantiation of list
12131        List<ActivityManager.RunningAppProcessInfo> runList = null;
12132        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12133                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12134        int userId = UserHandle.getUserId(Binder.getCallingUid());
12135        synchronized (this) {
12136            // Iterate across all processes
12137            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12138                ProcessRecord app = mLruProcesses.get(i);
12139                if (!allUsers && app.userId != userId) {
12140                    continue;
12141                }
12142                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12143                    // Generate process state info for running application
12144                    ActivityManager.RunningAppProcessInfo currApp =
12145                        new ActivityManager.RunningAppProcessInfo(app.processName,
12146                                app.pid, app.getPackageList());
12147                    fillInProcMemInfo(app, currApp);
12148                    if (app.adjSource instanceof ProcessRecord) {
12149                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12150                        currApp.importanceReasonImportance =
12151                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12152                                        app.adjSourceProcState);
12153                    } else if (app.adjSource instanceof ActivityRecord) {
12154                        ActivityRecord r = (ActivityRecord)app.adjSource;
12155                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12156                    }
12157                    if (app.adjTarget instanceof ComponentName) {
12158                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12159                    }
12160                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12161                    //        + " lru=" + currApp.lru);
12162                    if (runList == null) {
12163                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12164                    }
12165                    runList.add(currApp);
12166                }
12167            }
12168        }
12169        return runList;
12170    }
12171
12172    public List<ApplicationInfo> getRunningExternalApplications() {
12173        enforceNotIsolatedCaller("getRunningExternalApplications");
12174        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12175        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12176        if (runningApps != null && runningApps.size() > 0) {
12177            Set<String> extList = new HashSet<String>();
12178            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12179                if (app.pkgList != null) {
12180                    for (String pkg : app.pkgList) {
12181                        extList.add(pkg);
12182                    }
12183                }
12184            }
12185            IPackageManager pm = AppGlobals.getPackageManager();
12186            for (String pkg : extList) {
12187                try {
12188                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12189                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12190                        retList.add(info);
12191                    }
12192                } catch (RemoteException e) {
12193                }
12194            }
12195        }
12196        return retList;
12197    }
12198
12199    @Override
12200    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12201        enforceNotIsolatedCaller("getMyMemoryState");
12202        synchronized (this) {
12203            ProcessRecord proc;
12204            synchronized (mPidsSelfLocked) {
12205                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12206            }
12207            fillInProcMemInfo(proc, outInfo);
12208        }
12209    }
12210
12211    @Override
12212    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12213        if (checkCallingPermission(android.Manifest.permission.DUMP)
12214                != PackageManager.PERMISSION_GRANTED) {
12215            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12216                    + Binder.getCallingPid()
12217                    + ", uid=" + Binder.getCallingUid()
12218                    + " without permission "
12219                    + android.Manifest.permission.DUMP);
12220            return;
12221        }
12222
12223        boolean dumpAll = false;
12224        boolean dumpClient = false;
12225        String dumpPackage = null;
12226
12227        int opti = 0;
12228        while (opti < args.length) {
12229            String opt = args[opti];
12230            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12231                break;
12232            }
12233            opti++;
12234            if ("-a".equals(opt)) {
12235                dumpAll = true;
12236            } else if ("-c".equals(opt)) {
12237                dumpClient = true;
12238            } else if ("-h".equals(opt)) {
12239                pw.println("Activity manager dump options:");
12240                pw.println("  [-a] [-c] [-h] [cmd] ...");
12241                pw.println("  cmd may be one of:");
12242                pw.println("    a[ctivities]: activity stack state");
12243                pw.println("    r[recents]: recent activities state");
12244                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12245                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12246                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12247                pw.println("    o[om]: out of memory management");
12248                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12249                pw.println("    provider [COMP_SPEC]: provider client-side state");
12250                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12251                pw.println("    service [COMP_SPEC]: service client-side state");
12252                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12253                pw.println("    all: dump all activities");
12254                pw.println("    top: dump the top activity");
12255                pw.println("    write: write all pending state to storage");
12256                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12257                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12258                pw.println("    a partial substring in a component name, a");
12259                pw.println("    hex object identifier.");
12260                pw.println("  -a: include all available server state.");
12261                pw.println("  -c: include client state.");
12262                return;
12263            } else {
12264                pw.println("Unknown argument: " + opt + "; use -h for help");
12265            }
12266        }
12267
12268        long origId = Binder.clearCallingIdentity();
12269        boolean more = false;
12270        // Is the caller requesting to dump a particular piece of data?
12271        if (opti < args.length) {
12272            String cmd = args[opti];
12273            opti++;
12274            if ("activities".equals(cmd) || "a".equals(cmd)) {
12275                synchronized (this) {
12276                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12277                }
12278            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12279                synchronized (this) {
12280                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12281                }
12282            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12283                String[] newArgs;
12284                String name;
12285                if (opti >= args.length) {
12286                    name = null;
12287                    newArgs = EMPTY_STRING_ARRAY;
12288                } else {
12289                    name = args[opti];
12290                    opti++;
12291                    newArgs = new String[args.length - opti];
12292                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12293                            args.length - opti);
12294                }
12295                synchronized (this) {
12296                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12297                }
12298            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12299                String[] newArgs;
12300                String name;
12301                if (opti >= args.length) {
12302                    name = null;
12303                    newArgs = EMPTY_STRING_ARRAY;
12304                } else {
12305                    name = args[opti];
12306                    opti++;
12307                    newArgs = new String[args.length - opti];
12308                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12309                            args.length - opti);
12310                }
12311                synchronized (this) {
12312                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12313                }
12314            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12315                String[] newArgs;
12316                String name;
12317                if (opti >= args.length) {
12318                    name = null;
12319                    newArgs = EMPTY_STRING_ARRAY;
12320                } else {
12321                    name = args[opti];
12322                    opti++;
12323                    newArgs = new String[args.length - opti];
12324                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12325                            args.length - opti);
12326                }
12327                synchronized (this) {
12328                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12329                }
12330            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12331                synchronized (this) {
12332                    dumpOomLocked(fd, pw, args, opti, true);
12333                }
12334            } else if ("provider".equals(cmd)) {
12335                String[] newArgs;
12336                String name;
12337                if (opti >= args.length) {
12338                    name = null;
12339                    newArgs = EMPTY_STRING_ARRAY;
12340                } else {
12341                    name = args[opti];
12342                    opti++;
12343                    newArgs = new String[args.length - opti];
12344                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12345                }
12346                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12347                    pw.println("No providers match: " + name);
12348                    pw.println("Use -h for help.");
12349                }
12350            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12351                synchronized (this) {
12352                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12353                }
12354            } else if ("service".equals(cmd)) {
12355                String[] newArgs;
12356                String name;
12357                if (opti >= args.length) {
12358                    name = null;
12359                    newArgs = EMPTY_STRING_ARRAY;
12360                } else {
12361                    name = args[opti];
12362                    opti++;
12363                    newArgs = new String[args.length - opti];
12364                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12365                            args.length - opti);
12366                }
12367                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12368                    pw.println("No services match: " + name);
12369                    pw.println("Use -h for help.");
12370                }
12371            } else if ("package".equals(cmd)) {
12372                String[] newArgs;
12373                if (opti >= args.length) {
12374                    pw.println("package: no package name specified");
12375                    pw.println("Use -h for help.");
12376                } else {
12377                    dumpPackage = args[opti];
12378                    opti++;
12379                    newArgs = new String[args.length - opti];
12380                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12381                            args.length - opti);
12382                    args = newArgs;
12383                    opti = 0;
12384                    more = true;
12385                }
12386            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12387                synchronized (this) {
12388                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12389                }
12390            } else if ("write".equals(cmd)) {
12391                mTaskPersister.flush();
12392                pw.println("All tasks persisted.");
12393                return;
12394            } else {
12395                // Dumping a single activity?
12396                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12397                    pw.println("Bad activity command, or no activities match: " + cmd);
12398                    pw.println("Use -h for help.");
12399                }
12400            }
12401            if (!more) {
12402                Binder.restoreCallingIdentity(origId);
12403                return;
12404            }
12405        }
12406
12407        // No piece of data specified, dump everything.
12408        synchronized (this) {
12409            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12410            pw.println();
12411            if (dumpAll) {
12412                pw.println("-------------------------------------------------------------------------------");
12413            }
12414            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12415            pw.println();
12416            if (dumpAll) {
12417                pw.println("-------------------------------------------------------------------------------");
12418            }
12419            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12420            pw.println();
12421            if (dumpAll) {
12422                pw.println("-------------------------------------------------------------------------------");
12423            }
12424            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12425            pw.println();
12426            if (dumpAll) {
12427                pw.println("-------------------------------------------------------------------------------");
12428            }
12429            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12430            pw.println();
12431            if (dumpAll) {
12432                pw.println("-------------------------------------------------------------------------------");
12433            }
12434            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12435            pw.println();
12436            if (dumpAll) {
12437                pw.println("-------------------------------------------------------------------------------");
12438            }
12439            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12440        }
12441        Binder.restoreCallingIdentity(origId);
12442    }
12443
12444    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12445            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12446        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12447
12448        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12449                dumpPackage);
12450        boolean needSep = printedAnything;
12451
12452        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12453                dumpPackage, needSep, "  mFocusedActivity: ");
12454        if (printed) {
12455            printedAnything = true;
12456            needSep = false;
12457        }
12458
12459        if (dumpPackage == null) {
12460            if (needSep) {
12461                pw.println();
12462            }
12463            needSep = true;
12464            printedAnything = true;
12465            mStackSupervisor.dump(pw, "  ");
12466        }
12467
12468        if (!printedAnything) {
12469            pw.println("  (nothing)");
12470        }
12471    }
12472
12473    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12474            int opti, boolean dumpAll, String dumpPackage) {
12475        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12476
12477        boolean printedAnything = false;
12478
12479        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12480            boolean printedHeader = false;
12481
12482            final int N = mRecentTasks.size();
12483            for (int i=0; i<N; i++) {
12484                TaskRecord tr = mRecentTasks.get(i);
12485                if (dumpPackage != null) {
12486                    if (tr.realActivity == null ||
12487                            !dumpPackage.equals(tr.realActivity)) {
12488                        continue;
12489                    }
12490                }
12491                if (!printedHeader) {
12492                    pw.println("  Recent tasks:");
12493                    printedHeader = true;
12494                    printedAnything = true;
12495                }
12496                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12497                        pw.println(tr);
12498                if (dumpAll) {
12499                    mRecentTasks.get(i).dump(pw, "    ");
12500                }
12501            }
12502        }
12503
12504        if (!printedAnything) {
12505            pw.println("  (nothing)");
12506        }
12507    }
12508
12509    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12510            int opti, boolean dumpAll, String dumpPackage) {
12511        boolean needSep = false;
12512        boolean printedAnything = false;
12513        int numPers = 0;
12514
12515        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12516
12517        if (dumpAll) {
12518            final int NP = mProcessNames.getMap().size();
12519            for (int ip=0; ip<NP; ip++) {
12520                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12521                final int NA = procs.size();
12522                for (int ia=0; ia<NA; ia++) {
12523                    ProcessRecord r = procs.valueAt(ia);
12524                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12525                        continue;
12526                    }
12527                    if (!needSep) {
12528                        pw.println("  All known processes:");
12529                        needSep = true;
12530                        printedAnything = true;
12531                    }
12532                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12533                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12534                        pw.print(" "); pw.println(r);
12535                    r.dump(pw, "    ");
12536                    if (r.persistent) {
12537                        numPers++;
12538                    }
12539                }
12540            }
12541        }
12542
12543        if (mIsolatedProcesses.size() > 0) {
12544            boolean printed = false;
12545            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12546                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12547                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12548                    continue;
12549                }
12550                if (!printed) {
12551                    if (needSep) {
12552                        pw.println();
12553                    }
12554                    pw.println("  Isolated process list (sorted by uid):");
12555                    printedAnything = true;
12556                    printed = true;
12557                    needSep = true;
12558                }
12559                pw.println(String.format("%sIsolated #%2d: %s",
12560                        "    ", i, r.toString()));
12561            }
12562        }
12563
12564        if (mLruProcesses.size() > 0) {
12565            if (needSep) {
12566                pw.println();
12567            }
12568            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12569                    pw.print(" total, non-act at ");
12570                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12571                    pw.print(", non-svc at ");
12572                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12573                    pw.println("):");
12574            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12575            needSep = true;
12576            printedAnything = true;
12577        }
12578
12579        if (dumpAll || dumpPackage != null) {
12580            synchronized (mPidsSelfLocked) {
12581                boolean printed = false;
12582                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12583                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12584                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12585                        continue;
12586                    }
12587                    if (!printed) {
12588                        if (needSep) pw.println();
12589                        needSep = true;
12590                        pw.println("  PID mappings:");
12591                        printed = true;
12592                        printedAnything = true;
12593                    }
12594                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12595                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12596                }
12597            }
12598        }
12599
12600        if (mForegroundProcesses.size() > 0) {
12601            synchronized (mPidsSelfLocked) {
12602                boolean printed = false;
12603                for (int i=0; i<mForegroundProcesses.size(); i++) {
12604                    ProcessRecord r = mPidsSelfLocked.get(
12605                            mForegroundProcesses.valueAt(i).pid);
12606                    if (dumpPackage != null && (r == null
12607                            || !r.pkgList.containsKey(dumpPackage))) {
12608                        continue;
12609                    }
12610                    if (!printed) {
12611                        if (needSep) pw.println();
12612                        needSep = true;
12613                        pw.println("  Foreground Processes:");
12614                        printed = true;
12615                        printedAnything = true;
12616                    }
12617                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12618                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12619                }
12620            }
12621        }
12622
12623        if (mPersistentStartingProcesses.size() > 0) {
12624            if (needSep) pw.println();
12625            needSep = true;
12626            printedAnything = true;
12627            pw.println("  Persisent processes that are starting:");
12628            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12629                    "Starting Norm", "Restarting PERS", dumpPackage);
12630        }
12631
12632        if (mRemovedProcesses.size() > 0) {
12633            if (needSep) pw.println();
12634            needSep = true;
12635            printedAnything = true;
12636            pw.println("  Processes that are being removed:");
12637            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12638                    "Removed Norm", "Removed PERS", dumpPackage);
12639        }
12640
12641        if (mProcessesOnHold.size() > 0) {
12642            if (needSep) pw.println();
12643            needSep = true;
12644            printedAnything = true;
12645            pw.println("  Processes that are on old until the system is ready:");
12646            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12647                    "OnHold Norm", "OnHold PERS", dumpPackage);
12648        }
12649
12650        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12651
12652        if (mProcessCrashTimes.getMap().size() > 0) {
12653            boolean printed = false;
12654            long now = SystemClock.uptimeMillis();
12655            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12656            final int NP = pmap.size();
12657            for (int ip=0; ip<NP; ip++) {
12658                String pname = pmap.keyAt(ip);
12659                SparseArray<Long> uids = pmap.valueAt(ip);
12660                final int N = uids.size();
12661                for (int i=0; i<N; i++) {
12662                    int puid = uids.keyAt(i);
12663                    ProcessRecord r = mProcessNames.get(pname, puid);
12664                    if (dumpPackage != null && (r == null
12665                            || !r.pkgList.containsKey(dumpPackage))) {
12666                        continue;
12667                    }
12668                    if (!printed) {
12669                        if (needSep) pw.println();
12670                        needSep = true;
12671                        pw.println("  Time since processes crashed:");
12672                        printed = true;
12673                        printedAnything = true;
12674                    }
12675                    pw.print("    Process "); pw.print(pname);
12676                            pw.print(" uid "); pw.print(puid);
12677                            pw.print(": last crashed ");
12678                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12679                            pw.println(" ago");
12680                }
12681            }
12682        }
12683
12684        if (mBadProcesses.getMap().size() > 0) {
12685            boolean printed = false;
12686            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12687            final int NP = pmap.size();
12688            for (int ip=0; ip<NP; ip++) {
12689                String pname = pmap.keyAt(ip);
12690                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12691                final int N = uids.size();
12692                for (int i=0; i<N; i++) {
12693                    int puid = uids.keyAt(i);
12694                    ProcessRecord r = mProcessNames.get(pname, puid);
12695                    if (dumpPackage != null && (r == null
12696                            || !r.pkgList.containsKey(dumpPackage))) {
12697                        continue;
12698                    }
12699                    if (!printed) {
12700                        if (needSep) pw.println();
12701                        needSep = true;
12702                        pw.println("  Bad processes:");
12703                        printedAnything = true;
12704                    }
12705                    BadProcessInfo info = uids.valueAt(i);
12706                    pw.print("    Bad process "); pw.print(pname);
12707                            pw.print(" uid "); pw.print(puid);
12708                            pw.print(": crashed at time "); pw.println(info.time);
12709                    if (info.shortMsg != null) {
12710                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12711                    }
12712                    if (info.longMsg != null) {
12713                        pw.print("      Long msg: "); pw.println(info.longMsg);
12714                    }
12715                    if (info.stack != null) {
12716                        pw.println("      Stack:");
12717                        int lastPos = 0;
12718                        for (int pos=0; pos<info.stack.length(); pos++) {
12719                            if (info.stack.charAt(pos) == '\n') {
12720                                pw.print("        ");
12721                                pw.write(info.stack, lastPos, pos-lastPos);
12722                                pw.println();
12723                                lastPos = pos+1;
12724                            }
12725                        }
12726                        if (lastPos < info.stack.length()) {
12727                            pw.print("        ");
12728                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12729                            pw.println();
12730                        }
12731                    }
12732                }
12733            }
12734        }
12735
12736        if (dumpPackage == null) {
12737            pw.println();
12738            needSep = false;
12739            pw.println("  mStartedUsers:");
12740            for (int i=0; i<mStartedUsers.size(); i++) {
12741                UserStartedState uss = mStartedUsers.valueAt(i);
12742                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12743                        pw.print(": "); uss.dump("", pw);
12744            }
12745            pw.print("  mStartedUserArray: [");
12746            for (int i=0; i<mStartedUserArray.length; i++) {
12747                if (i > 0) pw.print(", ");
12748                pw.print(mStartedUserArray[i]);
12749            }
12750            pw.println("]");
12751            pw.print("  mUserLru: [");
12752            for (int i=0; i<mUserLru.size(); i++) {
12753                if (i > 0) pw.print(", ");
12754                pw.print(mUserLru.get(i));
12755            }
12756            pw.println("]");
12757            if (dumpAll) {
12758                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12759            }
12760            synchronized (mUserProfileGroupIdsSelfLocked) {
12761                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12762                    pw.println("  mUserProfileGroupIds:");
12763                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12764                        pw.print("    User #");
12765                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12766                        pw.print(" -> profile #");
12767                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12768                    }
12769                }
12770            }
12771        }
12772        if (mHomeProcess != null && (dumpPackage == null
12773                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12774            if (needSep) {
12775                pw.println();
12776                needSep = false;
12777            }
12778            pw.println("  mHomeProcess: " + mHomeProcess);
12779        }
12780        if (mPreviousProcess != null && (dumpPackage == null
12781                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12782            if (needSep) {
12783                pw.println();
12784                needSep = false;
12785            }
12786            pw.println("  mPreviousProcess: " + mPreviousProcess);
12787        }
12788        if (dumpAll) {
12789            StringBuilder sb = new StringBuilder(128);
12790            sb.append("  mPreviousProcessVisibleTime: ");
12791            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12792            pw.println(sb);
12793        }
12794        if (mHeavyWeightProcess != null && (dumpPackage == null
12795                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12796            if (needSep) {
12797                pw.println();
12798                needSep = false;
12799            }
12800            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12801        }
12802        if (dumpPackage == null) {
12803            pw.println("  mConfiguration: " + mConfiguration);
12804        }
12805        if (dumpAll) {
12806            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12807            if (mCompatModePackages.getPackages().size() > 0) {
12808                boolean printed = false;
12809                for (Map.Entry<String, Integer> entry
12810                        : mCompatModePackages.getPackages().entrySet()) {
12811                    String pkg = entry.getKey();
12812                    int mode = entry.getValue();
12813                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12814                        continue;
12815                    }
12816                    if (!printed) {
12817                        pw.println("  mScreenCompatPackages:");
12818                        printed = true;
12819                    }
12820                    pw.print("    "); pw.print(pkg); pw.print(": ");
12821                            pw.print(mode); pw.println();
12822                }
12823            }
12824        }
12825        if (dumpPackage == null) {
12826            if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) {
12827                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12828                        + " mLockScreenShown " + lockScreenShownToString());
12829            }
12830            if (mShuttingDown || mRunningVoice) {
12831                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12832            }
12833        }
12834        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12835                || mOrigWaitForDebugger) {
12836            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12837                    || dumpPackage.equals(mOrigDebugApp)) {
12838                if (needSep) {
12839                    pw.println();
12840                    needSep = false;
12841                }
12842                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12843                        + " mDebugTransient=" + mDebugTransient
12844                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12845            }
12846        }
12847        if (mOpenGlTraceApp != null) {
12848            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12849                if (needSep) {
12850                    pw.println();
12851                    needSep = false;
12852                }
12853                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12854            }
12855        }
12856        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12857                || mProfileFd != null) {
12858            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12859                if (needSep) {
12860                    pw.println();
12861                    needSep = false;
12862                }
12863                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12864                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12865                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12866                        + mAutoStopProfiler);
12867                pw.println("  mProfileType=" + mProfileType);
12868            }
12869        }
12870        if (dumpPackage == null) {
12871            if (mAlwaysFinishActivities || mController != null) {
12872                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12873                        + " mController=" + mController);
12874            }
12875            if (dumpAll) {
12876                pw.println("  Total persistent processes: " + numPers);
12877                pw.println("  mProcessesReady=" + mProcessesReady
12878                        + " mSystemReady=" + mSystemReady
12879                        + " mBooted=" + mBooted
12880                        + " mFactoryTest=" + mFactoryTest);
12881                pw.println("  mBooting=" + mBooting
12882                        + " mCallFinishBooting=" + mCallFinishBooting
12883                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12884                pw.print("  mLastPowerCheckRealtime=");
12885                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12886                        pw.println("");
12887                pw.print("  mLastPowerCheckUptime=");
12888                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12889                        pw.println("");
12890                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12891                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12892                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12893                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12894                        + " (" + mLruProcesses.size() + " total)"
12895                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12896                        + " mNumServiceProcs=" + mNumServiceProcs
12897                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12898                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12899                        + " mLastMemoryLevel" + mLastMemoryLevel
12900                        + " mLastNumProcesses" + mLastNumProcesses);
12901                long now = SystemClock.uptimeMillis();
12902                pw.print("  mLastIdleTime=");
12903                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12904                        pw.print(" mLowRamSinceLastIdle=");
12905                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12906                        pw.println();
12907            }
12908        }
12909
12910        if (!printedAnything) {
12911            pw.println("  (nothing)");
12912        }
12913    }
12914
12915    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12916            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12917        if (mProcessesToGc.size() > 0) {
12918            boolean printed = false;
12919            long now = SystemClock.uptimeMillis();
12920            for (int i=0; i<mProcessesToGc.size(); i++) {
12921                ProcessRecord proc = mProcessesToGc.get(i);
12922                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12923                    continue;
12924                }
12925                if (!printed) {
12926                    if (needSep) pw.println();
12927                    needSep = true;
12928                    pw.println("  Processes that are waiting to GC:");
12929                    printed = true;
12930                }
12931                pw.print("    Process "); pw.println(proc);
12932                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12933                        pw.print(", last gced=");
12934                        pw.print(now-proc.lastRequestedGc);
12935                        pw.print(" ms ago, last lowMem=");
12936                        pw.print(now-proc.lastLowMemory);
12937                        pw.println(" ms ago");
12938
12939            }
12940        }
12941        return needSep;
12942    }
12943
12944    void printOomLevel(PrintWriter pw, String name, int adj) {
12945        pw.print("    ");
12946        if (adj >= 0) {
12947            pw.print(' ');
12948            if (adj < 10) pw.print(' ');
12949        } else {
12950            if (adj > -10) pw.print(' ');
12951        }
12952        pw.print(adj);
12953        pw.print(": ");
12954        pw.print(name);
12955        pw.print(" (");
12956        pw.print(mProcessList.getMemLevel(adj)/1024);
12957        pw.println(" kB)");
12958    }
12959
12960    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12961            int opti, boolean dumpAll) {
12962        boolean needSep = false;
12963
12964        if (mLruProcesses.size() > 0) {
12965            if (needSep) pw.println();
12966            needSep = true;
12967            pw.println("  OOM levels:");
12968            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12969            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12970            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12971            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12972            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12973            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12974            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12975            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12976            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12977            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12978            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12979            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12980            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12981            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12982
12983            if (needSep) pw.println();
12984            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12985                    pw.print(" total, non-act at ");
12986                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12987                    pw.print(", non-svc at ");
12988                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12989                    pw.println("):");
12990            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12991            needSep = true;
12992        }
12993
12994        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12995
12996        pw.println();
12997        pw.println("  mHomeProcess: " + mHomeProcess);
12998        pw.println("  mPreviousProcess: " + mPreviousProcess);
12999        if (mHeavyWeightProcess != null) {
13000            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13001        }
13002
13003        return true;
13004    }
13005
13006    /**
13007     * There are three ways to call this:
13008     *  - no provider specified: dump all the providers
13009     *  - a flattened component name that matched an existing provider was specified as the
13010     *    first arg: dump that one provider
13011     *  - the first arg isn't the flattened component name of an existing provider:
13012     *    dump all providers whose component contains the first arg as a substring
13013     */
13014    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13015            int opti, boolean dumpAll) {
13016        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13017    }
13018
13019    static class ItemMatcher {
13020        ArrayList<ComponentName> components;
13021        ArrayList<String> strings;
13022        ArrayList<Integer> objects;
13023        boolean all;
13024
13025        ItemMatcher() {
13026            all = true;
13027        }
13028
13029        void build(String name) {
13030            ComponentName componentName = ComponentName.unflattenFromString(name);
13031            if (componentName != null) {
13032                if (components == null) {
13033                    components = new ArrayList<ComponentName>();
13034                }
13035                components.add(componentName);
13036                all = false;
13037            } else {
13038                int objectId = 0;
13039                // Not a '/' separated full component name; maybe an object ID?
13040                try {
13041                    objectId = Integer.parseInt(name, 16);
13042                    if (objects == null) {
13043                        objects = new ArrayList<Integer>();
13044                    }
13045                    objects.add(objectId);
13046                    all = false;
13047                } catch (RuntimeException e) {
13048                    // Not an integer; just do string match.
13049                    if (strings == null) {
13050                        strings = new ArrayList<String>();
13051                    }
13052                    strings.add(name);
13053                    all = false;
13054                }
13055            }
13056        }
13057
13058        int build(String[] args, int opti) {
13059            for (; opti<args.length; opti++) {
13060                String name = args[opti];
13061                if ("--".equals(name)) {
13062                    return opti+1;
13063                }
13064                build(name);
13065            }
13066            return opti;
13067        }
13068
13069        boolean match(Object object, ComponentName comp) {
13070            if (all) {
13071                return true;
13072            }
13073            if (components != null) {
13074                for (int i=0; i<components.size(); i++) {
13075                    if (components.get(i).equals(comp)) {
13076                        return true;
13077                    }
13078                }
13079            }
13080            if (objects != null) {
13081                for (int i=0; i<objects.size(); i++) {
13082                    if (System.identityHashCode(object) == objects.get(i)) {
13083                        return true;
13084                    }
13085                }
13086            }
13087            if (strings != null) {
13088                String flat = comp.flattenToString();
13089                for (int i=0; i<strings.size(); i++) {
13090                    if (flat.contains(strings.get(i))) {
13091                        return true;
13092                    }
13093                }
13094            }
13095            return false;
13096        }
13097    }
13098
13099    /**
13100     * There are three things that cmd can be:
13101     *  - a flattened component name that matches an existing activity
13102     *  - the cmd arg isn't the flattened component name of an existing activity:
13103     *    dump all activity whose component contains the cmd as a substring
13104     *  - A hex number of the ActivityRecord object instance.
13105     */
13106    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13107            int opti, boolean dumpAll) {
13108        ArrayList<ActivityRecord> activities;
13109
13110        synchronized (this) {
13111            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13112        }
13113
13114        if (activities.size() <= 0) {
13115            return false;
13116        }
13117
13118        String[] newArgs = new String[args.length - opti];
13119        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13120
13121        TaskRecord lastTask = null;
13122        boolean needSep = false;
13123        for (int i=activities.size()-1; i>=0; i--) {
13124            ActivityRecord r = activities.get(i);
13125            if (needSep) {
13126                pw.println();
13127            }
13128            needSep = true;
13129            synchronized (this) {
13130                if (lastTask != r.task) {
13131                    lastTask = r.task;
13132                    pw.print("TASK "); pw.print(lastTask.affinity);
13133                            pw.print(" id="); pw.println(lastTask.taskId);
13134                    if (dumpAll) {
13135                        lastTask.dump(pw, "  ");
13136                    }
13137                }
13138            }
13139            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13140        }
13141        return true;
13142    }
13143
13144    /**
13145     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13146     * there is a thread associated with the activity.
13147     */
13148    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13149            final ActivityRecord r, String[] args, boolean dumpAll) {
13150        String innerPrefix = prefix + "  ";
13151        synchronized (this) {
13152            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13153                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13154                    pw.print(" pid=");
13155                    if (r.app != null) pw.println(r.app.pid);
13156                    else pw.println("(not running)");
13157            if (dumpAll) {
13158                r.dump(pw, innerPrefix);
13159            }
13160        }
13161        if (r.app != null && r.app.thread != null) {
13162            // flush anything that is already in the PrintWriter since the thread is going
13163            // to write to the file descriptor directly
13164            pw.flush();
13165            try {
13166                TransferPipe tp = new TransferPipe();
13167                try {
13168                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13169                            r.appToken, innerPrefix, args);
13170                    tp.go(fd);
13171                } finally {
13172                    tp.kill();
13173                }
13174            } catch (IOException e) {
13175                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13176            } catch (RemoteException e) {
13177                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13178            }
13179        }
13180    }
13181
13182    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13183            int opti, boolean dumpAll, String dumpPackage) {
13184        boolean needSep = false;
13185        boolean onlyHistory = false;
13186        boolean printedAnything = false;
13187
13188        if ("history".equals(dumpPackage)) {
13189            if (opti < args.length && "-s".equals(args[opti])) {
13190                dumpAll = false;
13191            }
13192            onlyHistory = true;
13193            dumpPackage = null;
13194        }
13195
13196        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13197        if (!onlyHistory && dumpAll) {
13198            if (mRegisteredReceivers.size() > 0) {
13199                boolean printed = false;
13200                Iterator it = mRegisteredReceivers.values().iterator();
13201                while (it.hasNext()) {
13202                    ReceiverList r = (ReceiverList)it.next();
13203                    if (dumpPackage != null && (r.app == null ||
13204                            !dumpPackage.equals(r.app.info.packageName))) {
13205                        continue;
13206                    }
13207                    if (!printed) {
13208                        pw.println("  Registered Receivers:");
13209                        needSep = true;
13210                        printed = true;
13211                        printedAnything = true;
13212                    }
13213                    pw.print("  * "); pw.println(r);
13214                    r.dump(pw, "    ");
13215                }
13216            }
13217
13218            if (mReceiverResolver.dump(pw, needSep ?
13219                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13220                    "    ", dumpPackage, false)) {
13221                needSep = true;
13222                printedAnything = true;
13223            }
13224        }
13225
13226        for (BroadcastQueue q : mBroadcastQueues) {
13227            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13228            printedAnything |= needSep;
13229        }
13230
13231        needSep = true;
13232
13233        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13234            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13235                if (needSep) {
13236                    pw.println();
13237                }
13238                needSep = true;
13239                printedAnything = true;
13240                pw.print("  Sticky broadcasts for user ");
13241                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13242                StringBuilder sb = new StringBuilder(128);
13243                for (Map.Entry<String, ArrayList<Intent>> ent
13244                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13245                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13246                    if (dumpAll) {
13247                        pw.println(":");
13248                        ArrayList<Intent> intents = ent.getValue();
13249                        final int N = intents.size();
13250                        for (int i=0; i<N; i++) {
13251                            sb.setLength(0);
13252                            sb.append("    Intent: ");
13253                            intents.get(i).toShortString(sb, false, true, false, false);
13254                            pw.println(sb.toString());
13255                            Bundle bundle = intents.get(i).getExtras();
13256                            if (bundle != null) {
13257                                pw.print("      ");
13258                                pw.println(bundle.toString());
13259                            }
13260                        }
13261                    } else {
13262                        pw.println("");
13263                    }
13264                }
13265            }
13266        }
13267
13268        if (!onlyHistory && dumpAll) {
13269            pw.println();
13270            for (BroadcastQueue queue : mBroadcastQueues) {
13271                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13272                        + queue.mBroadcastsScheduled);
13273            }
13274            pw.println("  mHandler:");
13275            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13276            needSep = true;
13277            printedAnything = true;
13278        }
13279
13280        if (!printedAnything) {
13281            pw.println("  (nothing)");
13282        }
13283    }
13284
13285    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13286            int opti, boolean dumpAll, String dumpPackage) {
13287        boolean needSep;
13288        boolean printedAnything = false;
13289
13290        ItemMatcher matcher = new ItemMatcher();
13291        matcher.build(args, opti);
13292
13293        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13294
13295        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13296        printedAnything |= needSep;
13297
13298        if (mLaunchingProviders.size() > 0) {
13299            boolean printed = false;
13300            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13301                ContentProviderRecord r = mLaunchingProviders.get(i);
13302                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13303                    continue;
13304                }
13305                if (!printed) {
13306                    if (needSep) pw.println();
13307                    needSep = true;
13308                    pw.println("  Launching content providers:");
13309                    printed = true;
13310                    printedAnything = true;
13311                }
13312                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13313                        pw.println(r);
13314            }
13315        }
13316
13317        if (mGrantedUriPermissions.size() > 0) {
13318            boolean printed = false;
13319            int dumpUid = -2;
13320            if (dumpPackage != null) {
13321                try {
13322                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13323                } catch (NameNotFoundException e) {
13324                    dumpUid = -1;
13325                }
13326            }
13327            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13328                int uid = mGrantedUriPermissions.keyAt(i);
13329                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13330                    continue;
13331                }
13332                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13333                if (!printed) {
13334                    if (needSep) pw.println();
13335                    needSep = true;
13336                    pw.println("  Granted Uri Permissions:");
13337                    printed = true;
13338                    printedAnything = true;
13339                }
13340                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13341                for (UriPermission perm : perms.values()) {
13342                    pw.print("    "); pw.println(perm);
13343                    if (dumpAll) {
13344                        perm.dump(pw, "      ");
13345                    }
13346                }
13347            }
13348        }
13349
13350        if (!printedAnything) {
13351            pw.println("  (nothing)");
13352        }
13353    }
13354
13355    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13356            int opti, boolean dumpAll, String dumpPackage) {
13357        boolean printed = false;
13358
13359        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13360
13361        if (mIntentSenderRecords.size() > 0) {
13362            Iterator<WeakReference<PendingIntentRecord>> it
13363                    = mIntentSenderRecords.values().iterator();
13364            while (it.hasNext()) {
13365                WeakReference<PendingIntentRecord> ref = it.next();
13366                PendingIntentRecord rec = ref != null ? ref.get(): null;
13367                if (dumpPackage != null && (rec == null
13368                        || !dumpPackage.equals(rec.key.packageName))) {
13369                    continue;
13370                }
13371                printed = true;
13372                if (rec != null) {
13373                    pw.print("  * "); pw.println(rec);
13374                    if (dumpAll) {
13375                        rec.dump(pw, "    ");
13376                    }
13377                } else {
13378                    pw.print("  * "); pw.println(ref);
13379                }
13380            }
13381        }
13382
13383        if (!printed) {
13384            pw.println("  (nothing)");
13385        }
13386    }
13387
13388    private static final int dumpProcessList(PrintWriter pw,
13389            ActivityManagerService service, List list,
13390            String prefix, String normalLabel, String persistentLabel,
13391            String dumpPackage) {
13392        int numPers = 0;
13393        final int N = list.size()-1;
13394        for (int i=N; i>=0; i--) {
13395            ProcessRecord r = (ProcessRecord)list.get(i);
13396            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13397                continue;
13398            }
13399            pw.println(String.format("%s%s #%2d: %s",
13400                    prefix, (r.persistent ? persistentLabel : normalLabel),
13401                    i, r.toString()));
13402            if (r.persistent) {
13403                numPers++;
13404            }
13405        }
13406        return numPers;
13407    }
13408
13409    private static final boolean dumpProcessOomList(PrintWriter pw,
13410            ActivityManagerService service, List<ProcessRecord> origList,
13411            String prefix, String normalLabel, String persistentLabel,
13412            boolean inclDetails, String dumpPackage) {
13413
13414        ArrayList<Pair<ProcessRecord, Integer>> list
13415                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13416        for (int i=0; i<origList.size(); i++) {
13417            ProcessRecord r = origList.get(i);
13418            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13419                continue;
13420            }
13421            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13422        }
13423
13424        if (list.size() <= 0) {
13425            return false;
13426        }
13427
13428        Comparator<Pair<ProcessRecord, Integer>> comparator
13429                = new Comparator<Pair<ProcessRecord, Integer>>() {
13430            @Override
13431            public int compare(Pair<ProcessRecord, Integer> object1,
13432                    Pair<ProcessRecord, Integer> object2) {
13433                if (object1.first.setAdj != object2.first.setAdj) {
13434                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13435                }
13436                if (object1.second.intValue() != object2.second.intValue()) {
13437                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13438                }
13439                return 0;
13440            }
13441        };
13442
13443        Collections.sort(list, comparator);
13444
13445        final long curRealtime = SystemClock.elapsedRealtime();
13446        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13447        final long curUptime = SystemClock.uptimeMillis();
13448        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13449
13450        for (int i=list.size()-1; i>=0; i--) {
13451            ProcessRecord r = list.get(i).first;
13452            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13453            char schedGroup;
13454            switch (r.setSchedGroup) {
13455                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13456                    schedGroup = 'B';
13457                    break;
13458                case Process.THREAD_GROUP_DEFAULT:
13459                    schedGroup = 'F';
13460                    break;
13461                default:
13462                    schedGroup = '?';
13463                    break;
13464            }
13465            char foreground;
13466            if (r.foregroundActivities) {
13467                foreground = 'A';
13468            } else if (r.foregroundServices) {
13469                foreground = 'S';
13470            } else {
13471                foreground = ' ';
13472            }
13473            String procState = ProcessList.makeProcStateString(r.curProcState);
13474            pw.print(prefix);
13475            pw.print(r.persistent ? persistentLabel : normalLabel);
13476            pw.print(" #");
13477            int num = (origList.size()-1)-list.get(i).second;
13478            if (num < 10) pw.print(' ');
13479            pw.print(num);
13480            pw.print(": ");
13481            pw.print(oomAdj);
13482            pw.print(' ');
13483            pw.print(schedGroup);
13484            pw.print('/');
13485            pw.print(foreground);
13486            pw.print('/');
13487            pw.print(procState);
13488            pw.print(" trm:");
13489            if (r.trimMemoryLevel < 10) pw.print(' ');
13490            pw.print(r.trimMemoryLevel);
13491            pw.print(' ');
13492            pw.print(r.toShortString());
13493            pw.print(" (");
13494            pw.print(r.adjType);
13495            pw.println(')');
13496            if (r.adjSource != null || r.adjTarget != null) {
13497                pw.print(prefix);
13498                pw.print("    ");
13499                if (r.adjTarget instanceof ComponentName) {
13500                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13501                } else if (r.adjTarget != null) {
13502                    pw.print(r.adjTarget.toString());
13503                } else {
13504                    pw.print("{null}");
13505                }
13506                pw.print("<=");
13507                if (r.adjSource instanceof ProcessRecord) {
13508                    pw.print("Proc{");
13509                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13510                    pw.println("}");
13511                } else if (r.adjSource != null) {
13512                    pw.println(r.adjSource.toString());
13513                } else {
13514                    pw.println("{null}");
13515                }
13516            }
13517            if (inclDetails) {
13518                pw.print(prefix);
13519                pw.print("    ");
13520                pw.print("oom: max="); pw.print(r.maxAdj);
13521                pw.print(" curRaw="); pw.print(r.curRawAdj);
13522                pw.print(" setRaw="); pw.print(r.setRawAdj);
13523                pw.print(" cur="); pw.print(r.curAdj);
13524                pw.print(" set="); pw.println(r.setAdj);
13525                pw.print(prefix);
13526                pw.print("    ");
13527                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13528                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13529                pw.print(" lastPss="); pw.print(r.lastPss);
13530                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13531                pw.print(prefix);
13532                pw.print("    ");
13533                pw.print("cached="); pw.print(r.cached);
13534                pw.print(" empty="); pw.print(r.empty);
13535                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13536
13537                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13538                    if (r.lastWakeTime != 0) {
13539                        long wtime;
13540                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13541                        synchronized (stats) {
13542                            wtime = stats.getProcessWakeTime(r.info.uid,
13543                                    r.pid, curRealtime);
13544                        }
13545                        long timeUsed = wtime - r.lastWakeTime;
13546                        pw.print(prefix);
13547                        pw.print("    ");
13548                        pw.print("keep awake over ");
13549                        TimeUtils.formatDuration(realtimeSince, pw);
13550                        pw.print(" used ");
13551                        TimeUtils.formatDuration(timeUsed, pw);
13552                        pw.print(" (");
13553                        pw.print((timeUsed*100)/realtimeSince);
13554                        pw.println("%)");
13555                    }
13556                    if (r.lastCpuTime != 0) {
13557                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13558                        pw.print(prefix);
13559                        pw.print("    ");
13560                        pw.print("run cpu over ");
13561                        TimeUtils.formatDuration(uptimeSince, pw);
13562                        pw.print(" used ");
13563                        TimeUtils.formatDuration(timeUsed, pw);
13564                        pw.print(" (");
13565                        pw.print((timeUsed*100)/uptimeSince);
13566                        pw.println("%)");
13567                    }
13568                }
13569            }
13570        }
13571        return true;
13572    }
13573
13574    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13575            String[] args) {
13576        ArrayList<ProcessRecord> procs;
13577        synchronized (this) {
13578            if (args != null && args.length > start
13579                    && args[start].charAt(0) != '-') {
13580                procs = new ArrayList<ProcessRecord>();
13581                int pid = -1;
13582                try {
13583                    pid = Integer.parseInt(args[start]);
13584                } catch (NumberFormatException e) {
13585                }
13586                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13587                    ProcessRecord proc = mLruProcesses.get(i);
13588                    if (proc.pid == pid) {
13589                        procs.add(proc);
13590                    } else if (allPkgs && proc.pkgList != null
13591                            && proc.pkgList.containsKey(args[start])) {
13592                        procs.add(proc);
13593                    } else if (proc.processName.equals(args[start])) {
13594                        procs.add(proc);
13595                    }
13596                }
13597                if (procs.size() <= 0) {
13598                    return null;
13599                }
13600            } else {
13601                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13602            }
13603        }
13604        return procs;
13605    }
13606
13607    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13608            PrintWriter pw, String[] args) {
13609        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13610        if (procs == null) {
13611            pw.println("No process found for: " + args[0]);
13612            return;
13613        }
13614
13615        long uptime = SystemClock.uptimeMillis();
13616        long realtime = SystemClock.elapsedRealtime();
13617        pw.println("Applications Graphics Acceleration Info:");
13618        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13619
13620        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13621            ProcessRecord r = procs.get(i);
13622            if (r.thread != null) {
13623                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13624                pw.flush();
13625                try {
13626                    TransferPipe tp = new TransferPipe();
13627                    try {
13628                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13629                        tp.go(fd);
13630                    } finally {
13631                        tp.kill();
13632                    }
13633                } catch (IOException e) {
13634                    pw.println("Failure while dumping the app: " + r);
13635                    pw.flush();
13636                } catch (RemoteException e) {
13637                    pw.println("Got a RemoteException while dumping the app " + r);
13638                    pw.flush();
13639                }
13640            }
13641        }
13642    }
13643
13644    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13645        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13646        if (procs == null) {
13647            pw.println("No process found for: " + args[0]);
13648            return;
13649        }
13650
13651        pw.println("Applications Database Info:");
13652
13653        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13654            ProcessRecord r = procs.get(i);
13655            if (r.thread != null) {
13656                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13657                pw.flush();
13658                try {
13659                    TransferPipe tp = new TransferPipe();
13660                    try {
13661                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13662                        tp.go(fd);
13663                    } finally {
13664                        tp.kill();
13665                    }
13666                } catch (IOException e) {
13667                    pw.println("Failure while dumping the app: " + r);
13668                    pw.flush();
13669                } catch (RemoteException e) {
13670                    pw.println("Got a RemoteException while dumping the app " + r);
13671                    pw.flush();
13672                }
13673            }
13674        }
13675    }
13676
13677    final static class MemItem {
13678        final boolean isProc;
13679        final String label;
13680        final String shortLabel;
13681        final long pss;
13682        final int id;
13683        final boolean hasActivities;
13684        ArrayList<MemItem> subitems;
13685
13686        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13687                boolean _hasActivities) {
13688            isProc = true;
13689            label = _label;
13690            shortLabel = _shortLabel;
13691            pss = _pss;
13692            id = _id;
13693            hasActivities = _hasActivities;
13694        }
13695
13696        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13697            isProc = false;
13698            label = _label;
13699            shortLabel = _shortLabel;
13700            pss = _pss;
13701            id = _id;
13702            hasActivities = false;
13703        }
13704    }
13705
13706    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13707            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13708        if (sort && !isCompact) {
13709            Collections.sort(items, new Comparator<MemItem>() {
13710                @Override
13711                public int compare(MemItem lhs, MemItem rhs) {
13712                    if (lhs.pss < rhs.pss) {
13713                        return 1;
13714                    } else if (lhs.pss > rhs.pss) {
13715                        return -1;
13716                    }
13717                    return 0;
13718                }
13719            });
13720        }
13721
13722        for (int i=0; i<items.size(); i++) {
13723            MemItem mi = items.get(i);
13724            if (!isCompact) {
13725                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13726            } else if (mi.isProc) {
13727                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13728                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13729                pw.println(mi.hasActivities ? ",a" : ",e");
13730            } else {
13731                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13732                pw.println(mi.pss);
13733            }
13734            if (mi.subitems != null) {
13735                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13736                        true, isCompact);
13737            }
13738        }
13739    }
13740
13741    // These are in KB.
13742    static final long[] DUMP_MEM_BUCKETS = new long[] {
13743        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13744        120*1024, 160*1024, 200*1024,
13745        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13746        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13747    };
13748
13749    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13750            boolean stackLike) {
13751        int start = label.lastIndexOf('.');
13752        if (start >= 0) start++;
13753        else start = 0;
13754        int end = label.length();
13755        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13756            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13757                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13758                out.append(bucket);
13759                out.append(stackLike ? "MB." : "MB ");
13760                out.append(label, start, end);
13761                return;
13762            }
13763        }
13764        out.append(memKB/1024);
13765        out.append(stackLike ? "MB." : "MB ");
13766        out.append(label, start, end);
13767    }
13768
13769    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13770            ProcessList.NATIVE_ADJ,
13771            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13772            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13773            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13774            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13775            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13776            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13777    };
13778    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13779            "Native",
13780            "System", "Persistent", "Persistent Service", "Foreground",
13781            "Visible", "Perceptible",
13782            "Heavy Weight", "Backup",
13783            "A Services", "Home",
13784            "Previous", "B Services", "Cached"
13785    };
13786    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13787            "native",
13788            "sys", "pers", "persvc", "fore",
13789            "vis", "percept",
13790            "heavy", "backup",
13791            "servicea", "home",
13792            "prev", "serviceb", "cached"
13793    };
13794
13795    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13796            long realtime, boolean isCheckinRequest, boolean isCompact) {
13797        if (isCheckinRequest || isCompact) {
13798            // short checkin version
13799            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13800        } else {
13801            pw.println("Applications Memory Usage (kB):");
13802            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13803        }
13804    }
13805
13806    private static final int KSM_SHARED = 0;
13807    private static final int KSM_SHARING = 1;
13808    private static final int KSM_UNSHARED = 2;
13809    private static final int KSM_VOLATILE = 3;
13810
13811    private final long[] getKsmInfo() {
13812        long[] longOut = new long[4];
13813        final int[] SINGLE_LONG_FORMAT = new int[] {
13814            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13815        };
13816        long[] longTmp = new long[1];
13817        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13818                SINGLE_LONG_FORMAT, null, longTmp, null);
13819        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13820        longTmp[0] = 0;
13821        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13822                SINGLE_LONG_FORMAT, null, longTmp, null);
13823        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13824        longTmp[0] = 0;
13825        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13826                SINGLE_LONG_FORMAT, null, longTmp, null);
13827        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13828        longTmp[0] = 0;
13829        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13830                SINGLE_LONG_FORMAT, null, longTmp, null);
13831        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13832        return longOut;
13833    }
13834
13835    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13836            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13837        boolean dumpDetails = false;
13838        boolean dumpFullDetails = false;
13839        boolean dumpDalvik = false;
13840        boolean oomOnly = false;
13841        boolean isCompact = false;
13842        boolean localOnly = false;
13843        boolean packages = false;
13844
13845        int opti = 0;
13846        while (opti < args.length) {
13847            String opt = args[opti];
13848            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13849                break;
13850            }
13851            opti++;
13852            if ("-a".equals(opt)) {
13853                dumpDetails = true;
13854                dumpFullDetails = true;
13855                dumpDalvik = true;
13856            } else if ("-d".equals(opt)) {
13857                dumpDalvik = true;
13858            } else if ("-c".equals(opt)) {
13859                isCompact = true;
13860            } else if ("--oom".equals(opt)) {
13861                oomOnly = true;
13862            } else if ("--local".equals(opt)) {
13863                localOnly = true;
13864            } else if ("--package".equals(opt)) {
13865                packages = true;
13866            } else if ("-h".equals(opt)) {
13867                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13868                pw.println("  -a: include all available information for each process.");
13869                pw.println("  -d: include dalvik details when dumping process details.");
13870                pw.println("  -c: dump in a compact machine-parseable representation.");
13871                pw.println("  --oom: only show processes organized by oom adj.");
13872                pw.println("  --local: only collect details locally, don't call process.");
13873                pw.println("  --package: interpret process arg as package, dumping all");
13874                pw.println("             processes that have loaded that package.");
13875                pw.println("If [process] is specified it can be the name or ");
13876                pw.println("pid of a specific process to dump.");
13877                return;
13878            } else {
13879                pw.println("Unknown argument: " + opt + "; use -h for help");
13880            }
13881        }
13882
13883        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13884        long uptime = SystemClock.uptimeMillis();
13885        long realtime = SystemClock.elapsedRealtime();
13886        final long[] tmpLong = new long[1];
13887
13888        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13889        if (procs == null) {
13890            // No Java processes.  Maybe they want to print a native process.
13891            if (args != null && args.length > opti
13892                    && args[opti].charAt(0) != '-') {
13893                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13894                        = new ArrayList<ProcessCpuTracker.Stats>();
13895                updateCpuStatsNow();
13896                int findPid = -1;
13897                try {
13898                    findPid = Integer.parseInt(args[opti]);
13899                } catch (NumberFormatException e) {
13900                }
13901                synchronized (mProcessCpuTracker) {
13902                    final int N = mProcessCpuTracker.countStats();
13903                    for (int i=0; i<N; i++) {
13904                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13905                        if (st.pid == findPid || (st.baseName != null
13906                                && st.baseName.equals(args[opti]))) {
13907                            nativeProcs.add(st);
13908                        }
13909                    }
13910                }
13911                if (nativeProcs.size() > 0) {
13912                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13913                            isCompact);
13914                    Debug.MemoryInfo mi = null;
13915                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13916                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13917                        final int pid = r.pid;
13918                        if (!isCheckinRequest && dumpDetails) {
13919                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13920                        }
13921                        if (mi == null) {
13922                            mi = new Debug.MemoryInfo();
13923                        }
13924                        if (dumpDetails || (!brief && !oomOnly)) {
13925                            Debug.getMemoryInfo(pid, mi);
13926                        } else {
13927                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13928                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13929                        }
13930                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13931                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13932                        if (isCheckinRequest) {
13933                            pw.println();
13934                        }
13935                    }
13936                    return;
13937                }
13938            }
13939            pw.println("No process found for: " + args[opti]);
13940            return;
13941        }
13942
13943        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13944            dumpDetails = true;
13945        }
13946
13947        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13948
13949        String[] innerArgs = new String[args.length-opti];
13950        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13951
13952        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13953        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13954        long nativePss=0, dalvikPss=0, otherPss=0;
13955        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13956
13957        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13958        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13959                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13960
13961        long totalPss = 0;
13962        long cachedPss = 0;
13963
13964        Debug.MemoryInfo mi = null;
13965        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13966            final ProcessRecord r = procs.get(i);
13967            final IApplicationThread thread;
13968            final int pid;
13969            final int oomAdj;
13970            final boolean hasActivities;
13971            synchronized (this) {
13972                thread = r.thread;
13973                pid = r.pid;
13974                oomAdj = r.getSetAdjWithServices();
13975                hasActivities = r.activities.size() > 0;
13976            }
13977            if (thread != null) {
13978                if (!isCheckinRequest && dumpDetails) {
13979                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13980                }
13981                if (mi == null) {
13982                    mi = new Debug.MemoryInfo();
13983                }
13984                if (dumpDetails || (!brief && !oomOnly)) {
13985                    Debug.getMemoryInfo(pid, mi);
13986                } else {
13987                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13988                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13989                }
13990                if (dumpDetails) {
13991                    if (localOnly) {
13992                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13993                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13994                        if (isCheckinRequest) {
13995                            pw.println();
13996                        }
13997                    } else {
13998                        try {
13999                            pw.flush();
14000                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14001                                    dumpDalvik, innerArgs);
14002                        } catch (RemoteException e) {
14003                            if (!isCheckinRequest) {
14004                                pw.println("Got RemoteException!");
14005                                pw.flush();
14006                            }
14007                        }
14008                    }
14009                }
14010
14011                final long myTotalPss = mi.getTotalPss();
14012                final long myTotalUss = mi.getTotalUss();
14013
14014                synchronized (this) {
14015                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14016                        // Record this for posterity if the process has been stable.
14017                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14018                    }
14019                }
14020
14021                if (!isCheckinRequest && mi != null) {
14022                    totalPss += myTotalPss;
14023                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14024                            (hasActivities ? " / activities)" : ")"),
14025                            r.processName, myTotalPss, pid, hasActivities);
14026                    procMems.add(pssItem);
14027                    procMemsMap.put(pid, pssItem);
14028
14029                    nativePss += mi.nativePss;
14030                    dalvikPss += mi.dalvikPss;
14031                    otherPss += mi.otherPss;
14032                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14033                        long mem = mi.getOtherPss(j);
14034                        miscPss[j] += mem;
14035                        otherPss -= mem;
14036                    }
14037
14038                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14039                        cachedPss += myTotalPss;
14040                    }
14041
14042                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14043                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14044                                || oomIndex == (oomPss.length-1)) {
14045                            oomPss[oomIndex] += myTotalPss;
14046                            if (oomProcs[oomIndex] == null) {
14047                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14048                            }
14049                            oomProcs[oomIndex].add(pssItem);
14050                            break;
14051                        }
14052                    }
14053                }
14054            }
14055        }
14056
14057        long nativeProcTotalPss = 0;
14058
14059        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14060            // If we are showing aggregations, also look for native processes to
14061            // include so that our aggregations are more accurate.
14062            updateCpuStatsNow();
14063            synchronized (mProcessCpuTracker) {
14064                final int N = mProcessCpuTracker.countStats();
14065                for (int i=0; i<N; i++) {
14066                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14067                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14068                        if (mi == null) {
14069                            mi = new Debug.MemoryInfo();
14070                        }
14071                        if (!brief && !oomOnly) {
14072                            Debug.getMemoryInfo(st.pid, mi);
14073                        } else {
14074                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14075                            mi.nativePrivateDirty = (int)tmpLong[0];
14076                        }
14077
14078                        final long myTotalPss = mi.getTotalPss();
14079                        totalPss += myTotalPss;
14080                        nativeProcTotalPss += myTotalPss;
14081
14082                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14083                                st.name, myTotalPss, st.pid, false);
14084                        procMems.add(pssItem);
14085
14086                        nativePss += mi.nativePss;
14087                        dalvikPss += mi.dalvikPss;
14088                        otherPss += mi.otherPss;
14089                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14090                            long mem = mi.getOtherPss(j);
14091                            miscPss[j] += mem;
14092                            otherPss -= mem;
14093                        }
14094                        oomPss[0] += myTotalPss;
14095                        if (oomProcs[0] == null) {
14096                            oomProcs[0] = new ArrayList<MemItem>();
14097                        }
14098                        oomProcs[0].add(pssItem);
14099                    }
14100                }
14101            }
14102
14103            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14104
14105            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14106            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14107            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14108            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14109                String label = Debug.MemoryInfo.getOtherLabel(j);
14110                catMems.add(new MemItem(label, label, miscPss[j], j));
14111            }
14112
14113            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14114            for (int j=0; j<oomPss.length; j++) {
14115                if (oomPss[j] != 0) {
14116                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14117                            : DUMP_MEM_OOM_LABEL[j];
14118                    MemItem item = new MemItem(label, label, oomPss[j],
14119                            DUMP_MEM_OOM_ADJ[j]);
14120                    item.subitems = oomProcs[j];
14121                    oomMems.add(item);
14122                }
14123            }
14124
14125            if (!brief && !oomOnly && !isCompact) {
14126                pw.println();
14127                pw.println("Total PSS by process:");
14128                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14129                pw.println();
14130            }
14131            if (!isCompact) {
14132                pw.println("Total PSS by OOM adjustment:");
14133            }
14134            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14135            if (!brief && !oomOnly) {
14136                PrintWriter out = categoryPw != null ? categoryPw : pw;
14137                if (!isCompact) {
14138                    out.println();
14139                    out.println("Total PSS by category:");
14140                }
14141                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14142            }
14143            if (!isCompact) {
14144                pw.println();
14145            }
14146            MemInfoReader memInfo = new MemInfoReader();
14147            memInfo.readMemInfo();
14148            if (nativeProcTotalPss > 0) {
14149                synchronized (this) {
14150                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14151                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14152                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14153                }
14154            }
14155            if (!brief) {
14156                if (!isCompact) {
14157                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14158                    pw.print(" kB (status ");
14159                    switch (mLastMemoryLevel) {
14160                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14161                            pw.println("normal)");
14162                            break;
14163                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14164                            pw.println("moderate)");
14165                            break;
14166                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14167                            pw.println("low)");
14168                            break;
14169                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14170                            pw.println("critical)");
14171                            break;
14172                        default:
14173                            pw.print(mLastMemoryLevel);
14174                            pw.println(")");
14175                            break;
14176                    }
14177                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14178                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14179                            pw.print(cachedPss); pw.print(" cached pss + ");
14180                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14181                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14182                } else {
14183                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14184                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14185                            + memInfo.getFreeSizeKb()); pw.print(",");
14186                    pw.println(totalPss - cachedPss);
14187                }
14188            }
14189            if (!isCompact) {
14190                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14191                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14192                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14193                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14194                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14195                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14196                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14197            }
14198            if (!brief) {
14199                if (memInfo.getZramTotalSizeKb() != 0) {
14200                    if (!isCompact) {
14201                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14202                                pw.print(" kB physical used for ");
14203                                pw.print(memInfo.getSwapTotalSizeKb()
14204                                        - memInfo.getSwapFreeSizeKb());
14205                                pw.print(" kB in swap (");
14206                                pw.print(memInfo.getSwapTotalSizeKb());
14207                                pw.println(" kB total swap)");
14208                    } else {
14209                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14210                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14211                                pw.println(memInfo.getSwapFreeSizeKb());
14212                    }
14213                }
14214                final long[] ksm = getKsmInfo();
14215                if (!isCompact) {
14216                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14217                            || ksm[KSM_VOLATILE] != 0) {
14218                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14219                                pw.print(" kB saved from shared ");
14220                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14221                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14222                                pw.print(" kB unshared; ");
14223                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14224                    }
14225                    pw.print("   Tuning: ");
14226                    pw.print(ActivityManager.staticGetMemoryClass());
14227                    pw.print(" (large ");
14228                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14229                    pw.print("), oom ");
14230                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14231                    pw.print(" kB");
14232                    pw.print(", restore limit ");
14233                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14234                    pw.print(" kB");
14235                    if (ActivityManager.isLowRamDeviceStatic()) {
14236                        pw.print(" (low-ram)");
14237                    }
14238                    if (ActivityManager.isHighEndGfx()) {
14239                        pw.print(" (high-end-gfx)");
14240                    }
14241                    pw.println();
14242                } else {
14243                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14244                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14245                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14246                    pw.print("tuning,");
14247                    pw.print(ActivityManager.staticGetMemoryClass());
14248                    pw.print(',');
14249                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14250                    pw.print(',');
14251                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14252                    if (ActivityManager.isLowRamDeviceStatic()) {
14253                        pw.print(",low-ram");
14254                    }
14255                    if (ActivityManager.isHighEndGfx()) {
14256                        pw.print(",high-end-gfx");
14257                    }
14258                    pw.println();
14259                }
14260            }
14261        }
14262    }
14263
14264    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14265            String name) {
14266        sb.append("  ");
14267        sb.append(ProcessList.makeOomAdjString(oomAdj));
14268        sb.append(' ');
14269        sb.append(ProcessList.makeProcStateString(procState));
14270        sb.append(' ');
14271        ProcessList.appendRamKb(sb, pss);
14272        sb.append(" kB: ");
14273        sb.append(name);
14274    }
14275
14276    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14277        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14278        sb.append(" (");
14279        sb.append(mi.pid);
14280        sb.append(") ");
14281        sb.append(mi.adjType);
14282        sb.append('\n');
14283        if (mi.adjReason != null) {
14284            sb.append("                      ");
14285            sb.append(mi.adjReason);
14286            sb.append('\n');
14287        }
14288    }
14289
14290    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14291        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14292        for (int i=0, N=memInfos.size(); i<N; i++) {
14293            ProcessMemInfo mi = memInfos.get(i);
14294            infoMap.put(mi.pid, mi);
14295        }
14296        updateCpuStatsNow();
14297        synchronized (mProcessCpuTracker) {
14298            final int N = mProcessCpuTracker.countStats();
14299            for (int i=0; i<N; i++) {
14300                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14301                if (st.vsize > 0) {
14302                    long pss = Debug.getPss(st.pid, null);
14303                    if (pss > 0) {
14304                        if (infoMap.indexOfKey(st.pid) < 0) {
14305                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14306                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14307                            mi.pss = pss;
14308                            memInfos.add(mi);
14309                        }
14310                    }
14311                }
14312            }
14313        }
14314
14315        long totalPss = 0;
14316        for (int i=0, N=memInfos.size(); i<N; i++) {
14317            ProcessMemInfo mi = memInfos.get(i);
14318            if (mi.pss == 0) {
14319                mi.pss = Debug.getPss(mi.pid, null);
14320            }
14321            totalPss += mi.pss;
14322        }
14323        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14324            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14325                if (lhs.oomAdj != rhs.oomAdj) {
14326                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14327                }
14328                if (lhs.pss != rhs.pss) {
14329                    return lhs.pss < rhs.pss ? 1 : -1;
14330                }
14331                return 0;
14332            }
14333        });
14334
14335        StringBuilder tag = new StringBuilder(128);
14336        StringBuilder stack = new StringBuilder(128);
14337        tag.append("Low on memory -- ");
14338        appendMemBucket(tag, totalPss, "total", false);
14339        appendMemBucket(stack, totalPss, "total", true);
14340
14341        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14342        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14343        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14344
14345        boolean firstLine = true;
14346        int lastOomAdj = Integer.MIN_VALUE;
14347        long extraNativeRam = 0;
14348        long cachedPss = 0;
14349        for (int i=0, N=memInfos.size(); i<N; i++) {
14350            ProcessMemInfo mi = memInfos.get(i);
14351
14352            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14353                cachedPss += mi.pss;
14354            }
14355
14356            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14357                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14358                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14359                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14360                if (lastOomAdj != mi.oomAdj) {
14361                    lastOomAdj = mi.oomAdj;
14362                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14363                        tag.append(" / ");
14364                    }
14365                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14366                        if (firstLine) {
14367                            stack.append(":");
14368                            firstLine = false;
14369                        }
14370                        stack.append("\n\t at ");
14371                    } else {
14372                        stack.append("$");
14373                    }
14374                } else {
14375                    tag.append(" ");
14376                    stack.append("$");
14377                }
14378                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14379                    appendMemBucket(tag, mi.pss, mi.name, false);
14380                }
14381                appendMemBucket(stack, mi.pss, mi.name, true);
14382                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14383                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14384                    stack.append("(");
14385                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14386                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14387                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14388                            stack.append(":");
14389                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14390                        }
14391                    }
14392                    stack.append(")");
14393                }
14394            }
14395
14396            appendMemInfo(fullNativeBuilder, mi);
14397            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14398                // The short form only has native processes that are >= 1MB.
14399                if (mi.pss >= 1000) {
14400                    appendMemInfo(shortNativeBuilder, mi);
14401                } else {
14402                    extraNativeRam += mi.pss;
14403                }
14404            } else {
14405                // Short form has all other details, but if we have collected RAM
14406                // from smaller native processes let's dump a summary of that.
14407                if (extraNativeRam > 0) {
14408                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14409                            -1, extraNativeRam, "(Other native)");
14410                    shortNativeBuilder.append('\n');
14411                    extraNativeRam = 0;
14412                }
14413                appendMemInfo(fullJavaBuilder, mi);
14414            }
14415        }
14416
14417        fullJavaBuilder.append("           ");
14418        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14419        fullJavaBuilder.append(" kB: TOTAL\n");
14420
14421        MemInfoReader memInfo = new MemInfoReader();
14422        memInfo.readMemInfo();
14423        final long[] infos = memInfo.getRawInfo();
14424
14425        StringBuilder memInfoBuilder = new StringBuilder(1024);
14426        Debug.getMemInfo(infos);
14427        memInfoBuilder.append("  MemInfo: ");
14428        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14429        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14430        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14431        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14432        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14433        memInfoBuilder.append("           ");
14434        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14435        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14436        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14437        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14438        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14439            memInfoBuilder.append("  ZRAM: ");
14440            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14441            memInfoBuilder.append(" kB RAM, ");
14442            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14443            memInfoBuilder.append(" kB swap total, ");
14444            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14445            memInfoBuilder.append(" kB swap free\n");
14446        }
14447        final long[] ksm = getKsmInfo();
14448        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14449                || ksm[KSM_VOLATILE] != 0) {
14450            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14451            memInfoBuilder.append(" kB saved from shared ");
14452            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14453            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14454            memInfoBuilder.append(" kB unshared; ");
14455            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14456        }
14457        memInfoBuilder.append("  Free RAM: ");
14458        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14459                + memInfo.getFreeSizeKb());
14460        memInfoBuilder.append(" kB\n");
14461        memInfoBuilder.append("  Used RAM: ");
14462        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14463        memInfoBuilder.append(" kB\n");
14464        memInfoBuilder.append("  Lost RAM: ");
14465        memInfoBuilder.append(memInfo.getTotalSizeKb()
14466                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14467                - memInfo.getKernelUsedSizeKb());
14468        memInfoBuilder.append(" kB\n");
14469        Slog.i(TAG, "Low on memory:");
14470        Slog.i(TAG, shortNativeBuilder.toString());
14471        Slog.i(TAG, fullJavaBuilder.toString());
14472        Slog.i(TAG, memInfoBuilder.toString());
14473
14474        StringBuilder dropBuilder = new StringBuilder(1024);
14475        /*
14476        StringWriter oomSw = new StringWriter();
14477        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14478        StringWriter catSw = new StringWriter();
14479        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14480        String[] emptyArgs = new String[] { };
14481        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14482        oomPw.flush();
14483        String oomString = oomSw.toString();
14484        */
14485        dropBuilder.append("Low on memory:");
14486        dropBuilder.append(stack);
14487        dropBuilder.append('\n');
14488        dropBuilder.append(fullNativeBuilder);
14489        dropBuilder.append(fullJavaBuilder);
14490        dropBuilder.append('\n');
14491        dropBuilder.append(memInfoBuilder);
14492        dropBuilder.append('\n');
14493        /*
14494        dropBuilder.append(oomString);
14495        dropBuilder.append('\n');
14496        */
14497        StringWriter catSw = new StringWriter();
14498        synchronized (ActivityManagerService.this) {
14499            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14500            String[] emptyArgs = new String[] { };
14501            catPw.println();
14502            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14503            catPw.println();
14504            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14505                    false, false, null);
14506            catPw.println();
14507            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14508            catPw.flush();
14509        }
14510        dropBuilder.append(catSw.toString());
14511        addErrorToDropBox("lowmem", null, "system_server", null,
14512                null, tag.toString(), dropBuilder.toString(), null, null);
14513        //Slog.i(TAG, "Sent to dropbox:");
14514        //Slog.i(TAG, dropBuilder.toString());
14515        synchronized (ActivityManagerService.this) {
14516            long now = SystemClock.uptimeMillis();
14517            if (mLastMemUsageReportTime < now) {
14518                mLastMemUsageReportTime = now;
14519            }
14520        }
14521    }
14522
14523    /**
14524     * Searches array of arguments for the specified string
14525     * @param args array of argument strings
14526     * @param value value to search for
14527     * @return true if the value is contained in the array
14528     */
14529    private static boolean scanArgs(String[] args, String value) {
14530        if (args != null) {
14531            for (String arg : args) {
14532                if (value.equals(arg)) {
14533                    return true;
14534                }
14535            }
14536        }
14537        return false;
14538    }
14539
14540    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14541            ContentProviderRecord cpr, boolean always) {
14542        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14543
14544        if (!inLaunching || always) {
14545            synchronized (cpr) {
14546                cpr.launchingApp = null;
14547                cpr.notifyAll();
14548            }
14549            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14550            String names[] = cpr.info.authority.split(";");
14551            for (int j = 0; j < names.length; j++) {
14552                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14553            }
14554        }
14555
14556        for (int i=0; i<cpr.connections.size(); i++) {
14557            ContentProviderConnection conn = cpr.connections.get(i);
14558            if (conn.waiting) {
14559                // If this connection is waiting for the provider, then we don't
14560                // need to mess with its process unless we are always removing
14561                // or for some reason the provider is not currently launching.
14562                if (inLaunching && !always) {
14563                    continue;
14564                }
14565            }
14566            ProcessRecord capp = conn.client;
14567            conn.dead = true;
14568            if (conn.stableCount > 0) {
14569                if (!capp.persistent && capp.thread != null
14570                        && capp.pid != 0
14571                        && capp.pid != MY_PID) {
14572                    capp.kill("depends on provider "
14573                            + cpr.name.flattenToShortString()
14574                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14575                }
14576            } else if (capp.thread != null && conn.provider.provider != null) {
14577                try {
14578                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14579                } catch (RemoteException e) {
14580                }
14581                // In the protocol here, we don't expect the client to correctly
14582                // clean up this connection, we'll just remove it.
14583                cpr.connections.remove(i);
14584                conn.client.conProviders.remove(conn);
14585            }
14586        }
14587
14588        if (inLaunching && always) {
14589            mLaunchingProviders.remove(cpr);
14590        }
14591        return inLaunching;
14592    }
14593
14594    /**
14595     * Main code for cleaning up a process when it has gone away.  This is
14596     * called both as a result of the process dying, or directly when stopping
14597     * a process when running in single process mode.
14598     *
14599     * @return Returns true if the given process has been restarted, so the
14600     * app that was passed in must remain on the process lists.
14601     */
14602    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14603            boolean restarting, boolean allowRestart, int index) {
14604        if (index >= 0) {
14605            removeLruProcessLocked(app);
14606            ProcessList.remove(app.pid);
14607        }
14608
14609        mProcessesToGc.remove(app);
14610        mPendingPssProcesses.remove(app);
14611
14612        // Dismiss any open dialogs.
14613        if (app.crashDialog != null && !app.forceCrashReport) {
14614            app.crashDialog.dismiss();
14615            app.crashDialog = null;
14616        }
14617        if (app.anrDialog != null) {
14618            app.anrDialog.dismiss();
14619            app.anrDialog = null;
14620        }
14621        if (app.waitDialog != null) {
14622            app.waitDialog.dismiss();
14623            app.waitDialog = null;
14624        }
14625
14626        app.crashing = false;
14627        app.notResponding = false;
14628
14629        app.resetPackageList(mProcessStats);
14630        app.unlinkDeathRecipient();
14631        app.makeInactive(mProcessStats);
14632        app.waitingToKill = null;
14633        app.forcingToForeground = null;
14634        updateProcessForegroundLocked(app, false, false);
14635        app.foregroundActivities = false;
14636        app.hasShownUi = false;
14637        app.treatLikeActivity = false;
14638        app.hasAboveClient = false;
14639        app.hasClientActivities = false;
14640
14641        mServices.killServicesLocked(app, allowRestart);
14642
14643        boolean restart = false;
14644
14645        // Remove published content providers.
14646        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14647            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14648            final boolean always = app.bad || !allowRestart;
14649            if (removeDyingProviderLocked(app, cpr, always) || always) {
14650                // We left the provider in the launching list, need to
14651                // restart it.
14652                restart = true;
14653            }
14654
14655            cpr.provider = null;
14656            cpr.proc = null;
14657        }
14658        app.pubProviders.clear();
14659
14660        // Take care of any launching providers waiting for this process.
14661        if (checkAppInLaunchingProvidersLocked(app, false)) {
14662            restart = true;
14663        }
14664
14665        // Unregister from connected content providers.
14666        if (!app.conProviders.isEmpty()) {
14667            for (int i=0; i<app.conProviders.size(); i++) {
14668                ContentProviderConnection conn = app.conProviders.get(i);
14669                conn.provider.connections.remove(conn);
14670            }
14671            app.conProviders.clear();
14672        }
14673
14674        // At this point there may be remaining entries in mLaunchingProviders
14675        // where we were the only one waiting, so they are no longer of use.
14676        // Look for these and clean up if found.
14677        // XXX Commented out for now.  Trying to figure out a way to reproduce
14678        // the actual situation to identify what is actually going on.
14679        if (false) {
14680            for (int i=0; i<mLaunchingProviders.size(); i++) {
14681                ContentProviderRecord cpr = (ContentProviderRecord)
14682                        mLaunchingProviders.get(i);
14683                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14684                    synchronized (cpr) {
14685                        cpr.launchingApp = null;
14686                        cpr.notifyAll();
14687                    }
14688                }
14689            }
14690        }
14691
14692        skipCurrentReceiverLocked(app);
14693
14694        // Unregister any receivers.
14695        for (int i=app.receivers.size()-1; i>=0; i--) {
14696            removeReceiverLocked(app.receivers.valueAt(i));
14697        }
14698        app.receivers.clear();
14699
14700        // If the app is undergoing backup, tell the backup manager about it
14701        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14702            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14703                    + mBackupTarget.appInfo + " died during backup");
14704            try {
14705                IBackupManager bm = IBackupManager.Stub.asInterface(
14706                        ServiceManager.getService(Context.BACKUP_SERVICE));
14707                bm.agentDisconnected(app.info.packageName);
14708            } catch (RemoteException e) {
14709                // can't happen; backup manager is local
14710            }
14711        }
14712
14713        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14714            ProcessChangeItem item = mPendingProcessChanges.get(i);
14715            if (item.pid == app.pid) {
14716                mPendingProcessChanges.remove(i);
14717                mAvailProcessChanges.add(item);
14718            }
14719        }
14720        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14721
14722        // If the caller is restarting this app, then leave it in its
14723        // current lists and let the caller take care of it.
14724        if (restarting) {
14725            return false;
14726        }
14727
14728        if (!app.persistent || app.isolated) {
14729            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14730                    "Removing non-persistent process during cleanup: " + app);
14731            mProcessNames.remove(app.processName, app.uid);
14732            mIsolatedProcesses.remove(app.uid);
14733            if (mHeavyWeightProcess == app) {
14734                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14735                        mHeavyWeightProcess.userId, 0));
14736                mHeavyWeightProcess = null;
14737            }
14738        } else if (!app.removed) {
14739            // This app is persistent, so we need to keep its record around.
14740            // If it is not already on the pending app list, add it there
14741            // and start a new process for it.
14742            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14743                mPersistentStartingProcesses.add(app);
14744                restart = true;
14745            }
14746        }
14747        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14748                "Clean-up removing on hold: " + app);
14749        mProcessesOnHold.remove(app);
14750
14751        if (app == mHomeProcess) {
14752            mHomeProcess = null;
14753        }
14754        if (app == mPreviousProcess) {
14755            mPreviousProcess = null;
14756        }
14757
14758        if (restart && !app.isolated) {
14759            // We have components that still need to be running in the
14760            // process, so re-launch it.
14761            if (index < 0) {
14762                ProcessList.remove(app.pid);
14763            }
14764            mProcessNames.put(app.processName, app.uid, app);
14765            startProcessLocked(app, "restart", app.processName);
14766            return true;
14767        } else if (app.pid > 0 && app.pid != MY_PID) {
14768            // Goodbye!
14769            boolean removed;
14770            synchronized (mPidsSelfLocked) {
14771                mPidsSelfLocked.remove(app.pid);
14772                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14773            }
14774            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14775            if (app.isolated) {
14776                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14777            }
14778            app.setPid(0);
14779        }
14780        return false;
14781    }
14782
14783    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14784        // Look through the content providers we are waiting to have launched,
14785        // and if any run in this process then either schedule a restart of
14786        // the process or kill the client waiting for it if this process has
14787        // gone bad.
14788        int NL = mLaunchingProviders.size();
14789        boolean restart = false;
14790        for (int i=0; i<NL; i++) {
14791            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14792            if (cpr.launchingApp == app) {
14793                if (!alwaysBad && !app.bad) {
14794                    restart = true;
14795                } else {
14796                    removeDyingProviderLocked(app, cpr, true);
14797                    // cpr should have been removed from mLaunchingProviders
14798                    NL = mLaunchingProviders.size();
14799                    i--;
14800                }
14801            }
14802        }
14803        return restart;
14804    }
14805
14806    // =========================================================
14807    // SERVICES
14808    // =========================================================
14809
14810    @Override
14811    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14812            int flags) {
14813        enforceNotIsolatedCaller("getServices");
14814        synchronized (this) {
14815            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14816        }
14817    }
14818
14819    @Override
14820    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14821        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14822        synchronized (this) {
14823            return mServices.getRunningServiceControlPanelLocked(name);
14824        }
14825    }
14826
14827    @Override
14828    public ComponentName startService(IApplicationThread caller, Intent service,
14829            String resolvedType, int userId) {
14830        enforceNotIsolatedCaller("startService");
14831        // Refuse possible leaked file descriptors
14832        if (service != null && service.hasFileDescriptors() == true) {
14833            throw new IllegalArgumentException("File descriptors passed in Intent");
14834        }
14835
14836        if (DEBUG_SERVICE)
14837            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14838        synchronized(this) {
14839            final int callingPid = Binder.getCallingPid();
14840            final int callingUid = Binder.getCallingUid();
14841            final long origId = Binder.clearCallingIdentity();
14842            ComponentName res = mServices.startServiceLocked(caller, service,
14843                    resolvedType, callingPid, callingUid, userId);
14844            Binder.restoreCallingIdentity(origId);
14845            return res;
14846        }
14847    }
14848
14849    ComponentName startServiceInPackage(int uid,
14850            Intent service, String resolvedType, int userId) {
14851        synchronized(this) {
14852            if (DEBUG_SERVICE)
14853                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14854            final long origId = Binder.clearCallingIdentity();
14855            ComponentName res = mServices.startServiceLocked(null, service,
14856                    resolvedType, -1, uid, userId);
14857            Binder.restoreCallingIdentity(origId);
14858            return res;
14859        }
14860    }
14861
14862    @Override
14863    public int stopService(IApplicationThread caller, Intent service,
14864            String resolvedType, int userId) {
14865        enforceNotIsolatedCaller("stopService");
14866        // Refuse possible leaked file descriptors
14867        if (service != null && service.hasFileDescriptors() == true) {
14868            throw new IllegalArgumentException("File descriptors passed in Intent");
14869        }
14870
14871        synchronized(this) {
14872            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14873        }
14874    }
14875
14876    @Override
14877    public IBinder peekService(Intent service, String resolvedType) {
14878        enforceNotIsolatedCaller("peekService");
14879        // Refuse possible leaked file descriptors
14880        if (service != null && service.hasFileDescriptors() == true) {
14881            throw new IllegalArgumentException("File descriptors passed in Intent");
14882        }
14883        synchronized(this) {
14884            return mServices.peekServiceLocked(service, resolvedType);
14885        }
14886    }
14887
14888    @Override
14889    public boolean stopServiceToken(ComponentName className, IBinder token,
14890            int startId) {
14891        synchronized(this) {
14892            return mServices.stopServiceTokenLocked(className, token, startId);
14893        }
14894    }
14895
14896    @Override
14897    public void setServiceForeground(ComponentName className, IBinder token,
14898            int id, Notification notification, boolean removeNotification) {
14899        synchronized(this) {
14900            mServices.setServiceForegroundLocked(className, token, id, notification,
14901                    removeNotification);
14902        }
14903    }
14904
14905    @Override
14906    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14907            boolean requireFull, String name, String callerPackage) {
14908        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14909                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14910    }
14911
14912    int unsafeConvertIncomingUser(int userId) {
14913        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14914                ? mCurrentUserId : userId;
14915    }
14916
14917    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14918            int allowMode, String name, String callerPackage) {
14919        final int callingUserId = UserHandle.getUserId(callingUid);
14920        if (callingUserId == userId) {
14921            return userId;
14922        }
14923
14924        // Note that we may be accessing mCurrentUserId outside of a lock...
14925        // shouldn't be a big deal, if this is being called outside
14926        // of a locked context there is intrinsically a race with
14927        // the value the caller will receive and someone else changing it.
14928        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14929        // we will switch to the calling user if access to the current user fails.
14930        int targetUserId = unsafeConvertIncomingUser(userId);
14931
14932        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14933            final boolean allow;
14934            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14935                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14936                // If the caller has this permission, they always pass go.  And collect $200.
14937                allow = true;
14938            } else if (allowMode == ALLOW_FULL_ONLY) {
14939                // We require full access, sucks to be you.
14940                allow = false;
14941            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14942                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14943                // If the caller does not have either permission, they are always doomed.
14944                allow = false;
14945            } else if (allowMode == ALLOW_NON_FULL) {
14946                // We are blanket allowing non-full access, you lucky caller!
14947                allow = true;
14948            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14949                // We may or may not allow this depending on whether the two users are
14950                // in the same profile.
14951                synchronized (mUserProfileGroupIdsSelfLocked) {
14952                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14953                            UserInfo.NO_PROFILE_GROUP_ID);
14954                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14955                            UserInfo.NO_PROFILE_GROUP_ID);
14956                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14957                            && callingProfile == targetProfile;
14958                }
14959            } else {
14960                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14961            }
14962            if (!allow) {
14963                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14964                    // In this case, they would like to just execute as their
14965                    // owner user instead of failing.
14966                    targetUserId = callingUserId;
14967                } else {
14968                    StringBuilder builder = new StringBuilder(128);
14969                    builder.append("Permission Denial: ");
14970                    builder.append(name);
14971                    if (callerPackage != null) {
14972                        builder.append(" from ");
14973                        builder.append(callerPackage);
14974                    }
14975                    builder.append(" asks to run as user ");
14976                    builder.append(userId);
14977                    builder.append(" but is calling from user ");
14978                    builder.append(UserHandle.getUserId(callingUid));
14979                    builder.append("; this requires ");
14980                    builder.append(INTERACT_ACROSS_USERS_FULL);
14981                    if (allowMode != ALLOW_FULL_ONLY) {
14982                        builder.append(" or ");
14983                        builder.append(INTERACT_ACROSS_USERS);
14984                    }
14985                    String msg = builder.toString();
14986                    Slog.w(TAG, msg);
14987                    throw new SecurityException(msg);
14988                }
14989            }
14990        }
14991        if (!allowAll && targetUserId < 0) {
14992            throw new IllegalArgumentException(
14993                    "Call does not support special user #" + targetUserId);
14994        }
14995        // Check shell permission
14996        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14997            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14998                    targetUserId)) {
14999                throw new SecurityException("Shell does not have permission to access user "
15000                        + targetUserId + "\n " + Debug.getCallers(3));
15001            }
15002        }
15003        return targetUserId;
15004    }
15005
15006    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15007            String className, int flags) {
15008        boolean result = false;
15009        // For apps that don't have pre-defined UIDs, check for permission
15010        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15011            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15012                if (ActivityManager.checkUidPermission(
15013                        INTERACT_ACROSS_USERS,
15014                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15015                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15016                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15017                            + " requests FLAG_SINGLE_USER, but app does not hold "
15018                            + INTERACT_ACROSS_USERS;
15019                    Slog.w(TAG, msg);
15020                    throw new SecurityException(msg);
15021                }
15022                // Permission passed
15023                result = true;
15024            }
15025        } else if ("system".equals(componentProcessName)) {
15026            result = true;
15027        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15028            // Phone app and persistent apps are allowed to export singleuser providers.
15029            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15030                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15031        }
15032        if (DEBUG_MU) {
15033            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15034                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15035        }
15036        return result;
15037    }
15038
15039    /**
15040     * Checks to see if the caller is in the same app as the singleton
15041     * component, or the component is in a special app. It allows special apps
15042     * to export singleton components but prevents exporting singleton
15043     * components for regular apps.
15044     */
15045    boolean isValidSingletonCall(int callingUid, int componentUid) {
15046        int componentAppId = UserHandle.getAppId(componentUid);
15047        return UserHandle.isSameApp(callingUid, componentUid)
15048                || componentAppId == Process.SYSTEM_UID
15049                || componentAppId == Process.PHONE_UID
15050                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15051                        == PackageManager.PERMISSION_GRANTED;
15052    }
15053
15054    public int bindService(IApplicationThread caller, IBinder token,
15055            Intent service, String resolvedType,
15056            IServiceConnection connection, int flags, int userId) {
15057        enforceNotIsolatedCaller("bindService");
15058
15059        // Refuse possible leaked file descriptors
15060        if (service != null && service.hasFileDescriptors() == true) {
15061            throw new IllegalArgumentException("File descriptors passed in Intent");
15062        }
15063
15064        synchronized(this) {
15065            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15066                    connection, flags, userId);
15067        }
15068    }
15069
15070    public boolean unbindService(IServiceConnection connection) {
15071        synchronized (this) {
15072            return mServices.unbindServiceLocked(connection);
15073        }
15074    }
15075
15076    public void publishService(IBinder token, Intent intent, IBinder service) {
15077        // Refuse possible leaked file descriptors
15078        if (intent != null && intent.hasFileDescriptors() == true) {
15079            throw new IllegalArgumentException("File descriptors passed in Intent");
15080        }
15081
15082        synchronized(this) {
15083            if (!(token instanceof ServiceRecord)) {
15084                throw new IllegalArgumentException("Invalid service token");
15085            }
15086            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15087        }
15088    }
15089
15090    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15091        // Refuse possible leaked file descriptors
15092        if (intent != null && intent.hasFileDescriptors() == true) {
15093            throw new IllegalArgumentException("File descriptors passed in Intent");
15094        }
15095
15096        synchronized(this) {
15097            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15098        }
15099    }
15100
15101    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15102        synchronized(this) {
15103            if (!(token instanceof ServiceRecord)) {
15104                throw new IllegalArgumentException("Invalid service token");
15105            }
15106            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15107        }
15108    }
15109
15110    // =========================================================
15111    // BACKUP AND RESTORE
15112    // =========================================================
15113
15114    // Cause the target app to be launched if necessary and its backup agent
15115    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15116    // activity manager to announce its creation.
15117    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15118        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15119        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15120
15121        synchronized(this) {
15122            // !!! TODO: currently no check here that we're already bound
15123            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15124            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15125            synchronized (stats) {
15126                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15127            }
15128
15129            // Backup agent is now in use, its package can't be stopped.
15130            try {
15131                AppGlobals.getPackageManager().setPackageStoppedState(
15132                        app.packageName, false, UserHandle.getUserId(app.uid));
15133            } catch (RemoteException e) {
15134            } catch (IllegalArgumentException e) {
15135                Slog.w(TAG, "Failed trying to unstop package "
15136                        + app.packageName + ": " + e);
15137            }
15138
15139            BackupRecord r = new BackupRecord(ss, app, backupMode);
15140            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15141                    ? new ComponentName(app.packageName, app.backupAgentName)
15142                    : new ComponentName("android", "FullBackupAgent");
15143            // startProcessLocked() returns existing proc's record if it's already running
15144            ProcessRecord proc = startProcessLocked(app.processName, app,
15145                    false, 0, "backup", hostingName, false, false, false);
15146            if (proc == null) {
15147                Slog.e(TAG, "Unable to start backup agent process " + r);
15148                return false;
15149            }
15150
15151            r.app = proc;
15152            mBackupTarget = r;
15153            mBackupAppName = app.packageName;
15154
15155            // Try not to kill the process during backup
15156            updateOomAdjLocked(proc);
15157
15158            // If the process is already attached, schedule the creation of the backup agent now.
15159            // If it is not yet live, this will be done when it attaches to the framework.
15160            if (proc.thread != null) {
15161                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15162                try {
15163                    proc.thread.scheduleCreateBackupAgent(app,
15164                            compatibilityInfoForPackageLocked(app), backupMode);
15165                } catch (RemoteException e) {
15166                    // Will time out on the backup manager side
15167                }
15168            } else {
15169                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15170            }
15171            // Invariants: at this point, the target app process exists and the application
15172            // is either already running or in the process of coming up.  mBackupTarget and
15173            // mBackupAppName describe the app, so that when it binds back to the AM we
15174            // know that it's scheduled for a backup-agent operation.
15175        }
15176
15177        return true;
15178    }
15179
15180    @Override
15181    public void clearPendingBackup() {
15182        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15183        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15184
15185        synchronized (this) {
15186            mBackupTarget = null;
15187            mBackupAppName = null;
15188        }
15189    }
15190
15191    // A backup agent has just come up
15192    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15193        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15194                + " = " + agent);
15195
15196        synchronized(this) {
15197            if (!agentPackageName.equals(mBackupAppName)) {
15198                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15199                return;
15200            }
15201        }
15202
15203        long oldIdent = Binder.clearCallingIdentity();
15204        try {
15205            IBackupManager bm = IBackupManager.Stub.asInterface(
15206                    ServiceManager.getService(Context.BACKUP_SERVICE));
15207            bm.agentConnected(agentPackageName, agent);
15208        } catch (RemoteException e) {
15209            // can't happen; the backup manager service is local
15210        } catch (Exception e) {
15211            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15212            e.printStackTrace();
15213        } finally {
15214            Binder.restoreCallingIdentity(oldIdent);
15215        }
15216    }
15217
15218    // done with this agent
15219    public void unbindBackupAgent(ApplicationInfo appInfo) {
15220        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15221        if (appInfo == null) {
15222            Slog.w(TAG, "unbind backup agent for null app");
15223            return;
15224        }
15225
15226        synchronized(this) {
15227            try {
15228                if (mBackupAppName == null) {
15229                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15230                    return;
15231                }
15232
15233                if (!mBackupAppName.equals(appInfo.packageName)) {
15234                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15235                    return;
15236                }
15237
15238                // Not backing this app up any more; reset its OOM adjustment
15239                final ProcessRecord proc = mBackupTarget.app;
15240                updateOomAdjLocked(proc);
15241
15242                // If the app crashed during backup, 'thread' will be null here
15243                if (proc.thread != null) {
15244                    try {
15245                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15246                                compatibilityInfoForPackageLocked(appInfo));
15247                    } catch (Exception e) {
15248                        Slog.e(TAG, "Exception when unbinding backup agent:");
15249                        e.printStackTrace();
15250                    }
15251                }
15252            } finally {
15253                mBackupTarget = null;
15254                mBackupAppName = null;
15255            }
15256        }
15257    }
15258    // =========================================================
15259    // BROADCASTS
15260    // =========================================================
15261
15262    private final List getStickiesLocked(String action, IntentFilter filter,
15263            List cur, int userId) {
15264        final ContentResolver resolver = mContext.getContentResolver();
15265        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15266        if (stickies == null) {
15267            return cur;
15268        }
15269        final ArrayList<Intent> list = stickies.get(action);
15270        if (list == null) {
15271            return cur;
15272        }
15273        int N = list.size();
15274        for (int i=0; i<N; i++) {
15275            Intent intent = list.get(i);
15276            if (filter.match(resolver, intent, true, TAG) >= 0) {
15277                if (cur == null) {
15278                    cur = new ArrayList<Intent>();
15279                }
15280                cur.add(intent);
15281            }
15282        }
15283        return cur;
15284    }
15285
15286    boolean isPendingBroadcastProcessLocked(int pid) {
15287        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15288                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15289    }
15290
15291    void skipPendingBroadcastLocked(int pid) {
15292            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15293            for (BroadcastQueue queue : mBroadcastQueues) {
15294                queue.skipPendingBroadcastLocked(pid);
15295            }
15296    }
15297
15298    // The app just attached; send any pending broadcasts that it should receive
15299    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15300        boolean didSomething = false;
15301        for (BroadcastQueue queue : mBroadcastQueues) {
15302            didSomething |= queue.sendPendingBroadcastsLocked(app);
15303        }
15304        return didSomething;
15305    }
15306
15307    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15308            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15309        enforceNotIsolatedCaller("registerReceiver");
15310        int callingUid;
15311        int callingPid;
15312        synchronized(this) {
15313            ProcessRecord callerApp = null;
15314            if (caller != null) {
15315                callerApp = getRecordForAppLocked(caller);
15316                if (callerApp == null) {
15317                    throw new SecurityException(
15318                            "Unable to find app for caller " + caller
15319                            + " (pid=" + Binder.getCallingPid()
15320                            + ") when registering receiver " + receiver);
15321                }
15322                if (callerApp.info.uid != Process.SYSTEM_UID &&
15323                        !callerApp.pkgList.containsKey(callerPackage) &&
15324                        !"android".equals(callerPackage)) {
15325                    throw new SecurityException("Given caller package " + callerPackage
15326                            + " is not running in process " + callerApp);
15327                }
15328                callingUid = callerApp.info.uid;
15329                callingPid = callerApp.pid;
15330            } else {
15331                callerPackage = null;
15332                callingUid = Binder.getCallingUid();
15333                callingPid = Binder.getCallingPid();
15334            }
15335
15336            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15337                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15338
15339            List allSticky = null;
15340
15341            // Look for any matching sticky broadcasts...
15342            Iterator actions = filter.actionsIterator();
15343            if (actions != null) {
15344                while (actions.hasNext()) {
15345                    String action = (String)actions.next();
15346                    allSticky = getStickiesLocked(action, filter, allSticky,
15347                            UserHandle.USER_ALL);
15348                    allSticky = getStickiesLocked(action, filter, allSticky,
15349                            UserHandle.getUserId(callingUid));
15350                }
15351            } else {
15352                allSticky = getStickiesLocked(null, filter, allSticky,
15353                        UserHandle.USER_ALL);
15354                allSticky = getStickiesLocked(null, filter, allSticky,
15355                        UserHandle.getUserId(callingUid));
15356            }
15357
15358            // The first sticky in the list is returned directly back to
15359            // the client.
15360            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15361
15362            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15363                    + ": " + sticky);
15364
15365            if (receiver == null) {
15366                return sticky;
15367            }
15368
15369            ReceiverList rl
15370                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15371            if (rl == null) {
15372                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15373                        userId, receiver);
15374                if (rl.app != null) {
15375                    rl.app.receivers.add(rl);
15376                } else {
15377                    try {
15378                        receiver.asBinder().linkToDeath(rl, 0);
15379                    } catch (RemoteException e) {
15380                        return sticky;
15381                    }
15382                    rl.linkedToDeath = true;
15383                }
15384                mRegisteredReceivers.put(receiver.asBinder(), rl);
15385            } else if (rl.uid != callingUid) {
15386                throw new IllegalArgumentException(
15387                        "Receiver requested to register for uid " + callingUid
15388                        + " was previously registered for uid " + rl.uid);
15389            } else if (rl.pid != callingPid) {
15390                throw new IllegalArgumentException(
15391                        "Receiver requested to register for pid " + callingPid
15392                        + " was previously registered for pid " + rl.pid);
15393            } else if (rl.userId != userId) {
15394                throw new IllegalArgumentException(
15395                        "Receiver requested to register for user " + userId
15396                        + " was previously registered for user " + rl.userId);
15397            }
15398            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15399                    permission, callingUid, userId);
15400            rl.add(bf);
15401            if (!bf.debugCheck()) {
15402                Slog.w(TAG, "==> For Dynamic broadast");
15403            }
15404            mReceiverResolver.addFilter(bf);
15405
15406            // Enqueue broadcasts for all existing stickies that match
15407            // this filter.
15408            if (allSticky != null) {
15409                ArrayList receivers = new ArrayList();
15410                receivers.add(bf);
15411
15412                int N = allSticky.size();
15413                for (int i=0; i<N; i++) {
15414                    Intent intent = (Intent)allSticky.get(i);
15415                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15416                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15417                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15418                            null, null, false, true, true, -1);
15419                    queue.enqueueParallelBroadcastLocked(r);
15420                    queue.scheduleBroadcastsLocked();
15421                }
15422            }
15423
15424            return sticky;
15425        }
15426    }
15427
15428    public void unregisterReceiver(IIntentReceiver receiver) {
15429        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15430
15431        final long origId = Binder.clearCallingIdentity();
15432        try {
15433            boolean doTrim = false;
15434
15435            synchronized(this) {
15436                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15437                if (rl != null) {
15438                    if (rl.curBroadcast != null) {
15439                        BroadcastRecord r = rl.curBroadcast;
15440                        final boolean doNext = finishReceiverLocked(
15441                                receiver.asBinder(), r.resultCode, r.resultData,
15442                                r.resultExtras, r.resultAbort);
15443                        if (doNext) {
15444                            doTrim = true;
15445                            r.queue.processNextBroadcast(false);
15446                        }
15447                    }
15448
15449                    if (rl.app != null) {
15450                        rl.app.receivers.remove(rl);
15451                    }
15452                    removeReceiverLocked(rl);
15453                    if (rl.linkedToDeath) {
15454                        rl.linkedToDeath = false;
15455                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15456                    }
15457                }
15458            }
15459
15460            // If we actually concluded any broadcasts, we might now be able
15461            // to trim the recipients' apps from our working set
15462            if (doTrim) {
15463                trimApplications();
15464                return;
15465            }
15466
15467        } finally {
15468            Binder.restoreCallingIdentity(origId);
15469        }
15470    }
15471
15472    void removeReceiverLocked(ReceiverList rl) {
15473        mRegisteredReceivers.remove(rl.receiver.asBinder());
15474        int N = rl.size();
15475        for (int i=0; i<N; i++) {
15476            mReceiverResolver.removeFilter(rl.get(i));
15477        }
15478    }
15479
15480    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15481        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15482            ProcessRecord r = mLruProcesses.get(i);
15483            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15484                try {
15485                    r.thread.dispatchPackageBroadcast(cmd, packages);
15486                } catch (RemoteException ex) {
15487                }
15488            }
15489        }
15490    }
15491
15492    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15493            int callingUid, int[] users) {
15494        List<ResolveInfo> receivers = null;
15495        try {
15496            HashSet<ComponentName> singleUserReceivers = null;
15497            boolean scannedFirstReceivers = false;
15498            for (int user : users) {
15499                // Skip users that have Shell restrictions
15500                if (callingUid == Process.SHELL_UID
15501                        && getUserManagerLocked().hasUserRestriction(
15502                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15503                    continue;
15504                }
15505                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15506                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15507                if (user != 0 && newReceivers != null) {
15508                    // If this is not the primary user, we need to check for
15509                    // any receivers that should be filtered out.
15510                    for (int i=0; i<newReceivers.size(); i++) {
15511                        ResolveInfo ri = newReceivers.get(i);
15512                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15513                            newReceivers.remove(i);
15514                            i--;
15515                        }
15516                    }
15517                }
15518                if (newReceivers != null && newReceivers.size() == 0) {
15519                    newReceivers = null;
15520                }
15521                if (receivers == null) {
15522                    receivers = newReceivers;
15523                } else if (newReceivers != null) {
15524                    // We need to concatenate the additional receivers
15525                    // found with what we have do far.  This would be easy,
15526                    // but we also need to de-dup any receivers that are
15527                    // singleUser.
15528                    if (!scannedFirstReceivers) {
15529                        // Collect any single user receivers we had already retrieved.
15530                        scannedFirstReceivers = true;
15531                        for (int i=0; i<receivers.size(); i++) {
15532                            ResolveInfo ri = receivers.get(i);
15533                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15534                                ComponentName cn = new ComponentName(
15535                                        ri.activityInfo.packageName, ri.activityInfo.name);
15536                                if (singleUserReceivers == null) {
15537                                    singleUserReceivers = new HashSet<ComponentName>();
15538                                }
15539                                singleUserReceivers.add(cn);
15540                            }
15541                        }
15542                    }
15543                    // Add the new results to the existing results, tracking
15544                    // and de-dupping single user receivers.
15545                    for (int i=0; i<newReceivers.size(); i++) {
15546                        ResolveInfo ri = newReceivers.get(i);
15547                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15548                            ComponentName cn = new ComponentName(
15549                                    ri.activityInfo.packageName, ri.activityInfo.name);
15550                            if (singleUserReceivers == null) {
15551                                singleUserReceivers = new HashSet<ComponentName>();
15552                            }
15553                            if (!singleUserReceivers.contains(cn)) {
15554                                singleUserReceivers.add(cn);
15555                                receivers.add(ri);
15556                            }
15557                        } else {
15558                            receivers.add(ri);
15559                        }
15560                    }
15561                }
15562            }
15563        } catch (RemoteException ex) {
15564            // pm is in same process, this will never happen.
15565        }
15566        return receivers;
15567    }
15568
15569    private final int broadcastIntentLocked(ProcessRecord callerApp,
15570            String callerPackage, Intent intent, String resolvedType,
15571            IIntentReceiver resultTo, int resultCode, String resultData,
15572            Bundle map, String requiredPermission, int appOp,
15573            boolean ordered, boolean sticky, int callingPid, int callingUid,
15574            int userId) {
15575        intent = new Intent(intent);
15576
15577        // By default broadcasts do not go to stopped apps.
15578        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15579
15580        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15581            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15582            + " ordered=" + ordered + " userid=" + userId);
15583        if ((resultTo != null) && !ordered) {
15584            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15585        }
15586
15587        userId = handleIncomingUser(callingPid, callingUid, userId,
15588                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15589
15590        // Make sure that the user who is receiving this broadcast is started.
15591        // If not, we will just skip it.
15592
15593        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15594            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15595                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15596                Slog.w(TAG, "Skipping broadcast of " + intent
15597                        + ": user " + userId + " is stopped");
15598                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15599            }
15600        }
15601
15602        /*
15603         * Prevent non-system code (defined here to be non-persistent
15604         * processes) from sending protected broadcasts.
15605         */
15606        int callingAppId = UserHandle.getAppId(callingUid);
15607        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15608            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15609            || callingAppId == Process.NFC_UID || callingUid == 0) {
15610            // Always okay.
15611        } else if (callerApp == null || !callerApp.persistent) {
15612            try {
15613                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15614                        intent.getAction())) {
15615                    String msg = "Permission Denial: not allowed to send broadcast "
15616                            + intent.getAction() + " from pid="
15617                            + callingPid + ", uid=" + callingUid;
15618                    Slog.w(TAG, msg);
15619                    throw new SecurityException(msg);
15620                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15621                    // Special case for compatibility: we don't want apps to send this,
15622                    // but historically it has not been protected and apps may be using it
15623                    // to poke their own app widget.  So, instead of making it protected,
15624                    // just limit it to the caller.
15625                    if (callerApp == null) {
15626                        String msg = "Permission Denial: not allowed to send broadcast "
15627                                + intent.getAction() + " from unknown caller.";
15628                        Slog.w(TAG, msg);
15629                        throw new SecurityException(msg);
15630                    } else if (intent.getComponent() != null) {
15631                        // They are good enough to send to an explicit component...  verify
15632                        // it is being sent to the calling app.
15633                        if (!intent.getComponent().getPackageName().equals(
15634                                callerApp.info.packageName)) {
15635                            String msg = "Permission Denial: not allowed to send broadcast "
15636                                    + intent.getAction() + " to "
15637                                    + intent.getComponent().getPackageName() + " from "
15638                                    + callerApp.info.packageName;
15639                            Slog.w(TAG, msg);
15640                            throw new SecurityException(msg);
15641                        }
15642                    } else {
15643                        // Limit broadcast to their own package.
15644                        intent.setPackage(callerApp.info.packageName);
15645                    }
15646                }
15647            } catch (RemoteException e) {
15648                Slog.w(TAG, "Remote exception", e);
15649                return ActivityManager.BROADCAST_SUCCESS;
15650            }
15651        }
15652
15653        // Handle special intents: if this broadcast is from the package
15654        // manager about a package being removed, we need to remove all of
15655        // its activities from the history stack.
15656        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15657                intent.getAction());
15658        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15659                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15660                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15661                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15662                || uidRemoved) {
15663            if (checkComponentPermission(
15664                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15665                    callingPid, callingUid, -1, true)
15666                    == PackageManager.PERMISSION_GRANTED) {
15667                if (uidRemoved) {
15668                    final Bundle intentExtras = intent.getExtras();
15669                    final int uid = intentExtras != null
15670                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15671                    if (uid >= 0) {
15672                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15673                        synchronized (bs) {
15674                            bs.removeUidStatsLocked(uid);
15675                        }
15676                        mAppOpsService.uidRemoved(uid);
15677                    }
15678                } else {
15679                    // If resources are unavailable just force stop all
15680                    // those packages and flush the attribute cache as well.
15681                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15682                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15683                        if (list != null && (list.length > 0)) {
15684                            for (String pkg : list) {
15685                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15686                                        "storage unmount");
15687                            }
15688                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15689                            sendPackageBroadcastLocked(
15690                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15691                        }
15692                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15693                            intent.getAction())) {
15694                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15695                    } else {
15696                        Uri data = intent.getData();
15697                        String ssp;
15698                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15699                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15700                                    intent.getAction());
15701                            boolean fullUninstall = removed &&
15702                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15703                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15704                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15705                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15706                                        false, fullUninstall, userId,
15707                                        removed ? "pkg removed" : "pkg changed");
15708                            }
15709                            if (removed) {
15710                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15711                                        new String[] {ssp}, userId);
15712                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15713                                    mAppOpsService.packageRemoved(
15714                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15715
15716                                    // Remove all permissions granted from/to this package
15717                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15718                                }
15719                            }
15720                        }
15721                    }
15722                }
15723            } else {
15724                String msg = "Permission Denial: " + intent.getAction()
15725                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15726                        + ", uid=" + callingUid + ")"
15727                        + " requires "
15728                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15729                Slog.w(TAG, msg);
15730                throw new SecurityException(msg);
15731            }
15732
15733        // Special case for adding a package: by default turn on compatibility
15734        // mode.
15735        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15736            Uri data = intent.getData();
15737            String ssp;
15738            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15739                mCompatModePackages.handlePackageAddedLocked(ssp,
15740                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15741            }
15742        }
15743
15744        /*
15745         * If this is the time zone changed action, queue up a message that will reset the timezone
15746         * of all currently running processes. This message will get queued up before the broadcast
15747         * happens.
15748         */
15749        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15750            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15751        }
15752
15753        /*
15754         * If the user set the time, let all running processes know.
15755         */
15756        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15757            final int is24Hour = intent.getBooleanExtra(
15758                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15759            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15760            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15761            synchronized (stats) {
15762                stats.noteCurrentTimeChangedLocked();
15763            }
15764        }
15765
15766        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15767            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15768        }
15769
15770        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15771            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15772            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15773        }
15774
15775        // Add to the sticky list if requested.
15776        if (sticky) {
15777            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15778                    callingPid, callingUid)
15779                    != PackageManager.PERMISSION_GRANTED) {
15780                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15781                        + callingPid + ", uid=" + callingUid
15782                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15783                Slog.w(TAG, msg);
15784                throw new SecurityException(msg);
15785            }
15786            if (requiredPermission != null) {
15787                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15788                        + " and enforce permission " + requiredPermission);
15789                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15790            }
15791            if (intent.getComponent() != null) {
15792                throw new SecurityException(
15793                        "Sticky broadcasts can't target a specific component");
15794            }
15795            // We use userId directly here, since the "all" target is maintained
15796            // as a separate set of sticky broadcasts.
15797            if (userId != UserHandle.USER_ALL) {
15798                // But first, if this is not a broadcast to all users, then
15799                // make sure it doesn't conflict with an existing broadcast to
15800                // all users.
15801                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15802                        UserHandle.USER_ALL);
15803                if (stickies != null) {
15804                    ArrayList<Intent> list = stickies.get(intent.getAction());
15805                    if (list != null) {
15806                        int N = list.size();
15807                        int i;
15808                        for (i=0; i<N; i++) {
15809                            if (intent.filterEquals(list.get(i))) {
15810                                throw new IllegalArgumentException(
15811                                        "Sticky broadcast " + intent + " for user "
15812                                        + userId + " conflicts with existing global broadcast");
15813                            }
15814                        }
15815                    }
15816                }
15817            }
15818            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15819            if (stickies == null) {
15820                stickies = new ArrayMap<String, ArrayList<Intent>>();
15821                mStickyBroadcasts.put(userId, stickies);
15822            }
15823            ArrayList<Intent> list = stickies.get(intent.getAction());
15824            if (list == null) {
15825                list = new ArrayList<Intent>();
15826                stickies.put(intent.getAction(), list);
15827            }
15828            int N = list.size();
15829            int i;
15830            for (i=0; i<N; i++) {
15831                if (intent.filterEquals(list.get(i))) {
15832                    // This sticky already exists, replace it.
15833                    list.set(i, new Intent(intent));
15834                    break;
15835                }
15836            }
15837            if (i >= N) {
15838                list.add(new Intent(intent));
15839            }
15840        }
15841
15842        int[] users;
15843        if (userId == UserHandle.USER_ALL) {
15844            // Caller wants broadcast to go to all started users.
15845            users = mStartedUserArray;
15846        } else {
15847            // Caller wants broadcast to go to one specific user.
15848            users = new int[] {userId};
15849        }
15850
15851        // Figure out who all will receive this broadcast.
15852        List receivers = null;
15853        List<BroadcastFilter> registeredReceivers = null;
15854        // Need to resolve the intent to interested receivers...
15855        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15856                 == 0) {
15857            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15858        }
15859        if (intent.getComponent() == null) {
15860            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15861                // Query one target user at a time, excluding shell-restricted users
15862                UserManagerService ums = getUserManagerLocked();
15863                for (int i = 0; i < users.length; i++) {
15864                    if (ums.hasUserRestriction(
15865                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15866                        continue;
15867                    }
15868                    List<BroadcastFilter> registeredReceiversForUser =
15869                            mReceiverResolver.queryIntent(intent,
15870                                    resolvedType, false, users[i]);
15871                    if (registeredReceivers == null) {
15872                        registeredReceivers = registeredReceiversForUser;
15873                    } else if (registeredReceiversForUser != null) {
15874                        registeredReceivers.addAll(registeredReceiversForUser);
15875                    }
15876                }
15877            } else {
15878                registeredReceivers = mReceiverResolver.queryIntent(intent,
15879                        resolvedType, false, userId);
15880            }
15881        }
15882
15883        final boolean replacePending =
15884                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15885
15886        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15887                + " replacePending=" + replacePending);
15888
15889        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15890        if (!ordered && NR > 0) {
15891            // If we are not serializing this broadcast, then send the
15892            // registered receivers separately so they don't wait for the
15893            // components to be launched.
15894            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15895            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15896                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15897                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15898                    ordered, sticky, false, userId);
15899            if (DEBUG_BROADCAST) Slog.v(
15900                    TAG, "Enqueueing parallel broadcast " + r);
15901            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15902            if (!replaced) {
15903                queue.enqueueParallelBroadcastLocked(r);
15904                queue.scheduleBroadcastsLocked();
15905            }
15906            registeredReceivers = null;
15907            NR = 0;
15908        }
15909
15910        // Merge into one list.
15911        int ir = 0;
15912        if (receivers != null) {
15913            // A special case for PACKAGE_ADDED: do not allow the package
15914            // being added to see this broadcast.  This prevents them from
15915            // using this as a back door to get run as soon as they are
15916            // installed.  Maybe in the future we want to have a special install
15917            // broadcast or such for apps, but we'd like to deliberately make
15918            // this decision.
15919            String skipPackages[] = null;
15920            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15921                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15922                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15923                Uri data = intent.getData();
15924                if (data != null) {
15925                    String pkgName = data.getSchemeSpecificPart();
15926                    if (pkgName != null) {
15927                        skipPackages = new String[] { pkgName };
15928                    }
15929                }
15930            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15931                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15932            }
15933            if (skipPackages != null && (skipPackages.length > 0)) {
15934                for (String skipPackage : skipPackages) {
15935                    if (skipPackage != null) {
15936                        int NT = receivers.size();
15937                        for (int it=0; it<NT; it++) {
15938                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15939                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15940                                receivers.remove(it);
15941                                it--;
15942                                NT--;
15943                            }
15944                        }
15945                    }
15946                }
15947            }
15948
15949            int NT = receivers != null ? receivers.size() : 0;
15950            int it = 0;
15951            ResolveInfo curt = null;
15952            BroadcastFilter curr = null;
15953            while (it < NT && ir < NR) {
15954                if (curt == null) {
15955                    curt = (ResolveInfo)receivers.get(it);
15956                }
15957                if (curr == null) {
15958                    curr = registeredReceivers.get(ir);
15959                }
15960                if (curr.getPriority() >= curt.priority) {
15961                    // Insert this broadcast record into the final list.
15962                    receivers.add(it, curr);
15963                    ir++;
15964                    curr = null;
15965                    it++;
15966                    NT++;
15967                } else {
15968                    // Skip to the next ResolveInfo in the final list.
15969                    it++;
15970                    curt = null;
15971                }
15972            }
15973        }
15974        while (ir < NR) {
15975            if (receivers == null) {
15976                receivers = new ArrayList();
15977            }
15978            receivers.add(registeredReceivers.get(ir));
15979            ir++;
15980        }
15981
15982        if ((receivers != null && receivers.size() > 0)
15983                || resultTo != null) {
15984            BroadcastQueue queue = broadcastQueueForIntent(intent);
15985            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15986                    callerPackage, callingPid, callingUid, resolvedType,
15987                    requiredPermission, appOp, receivers, resultTo, resultCode,
15988                    resultData, map, ordered, sticky, false, userId);
15989            if (DEBUG_BROADCAST) Slog.v(
15990                    TAG, "Enqueueing ordered broadcast " + r
15991                    + ": prev had " + queue.mOrderedBroadcasts.size());
15992            if (DEBUG_BROADCAST) {
15993                int seq = r.intent.getIntExtra("seq", -1);
15994                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15995            }
15996            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15997            if (!replaced) {
15998                queue.enqueueOrderedBroadcastLocked(r);
15999                queue.scheduleBroadcastsLocked();
16000            }
16001        }
16002
16003        return ActivityManager.BROADCAST_SUCCESS;
16004    }
16005
16006    final Intent verifyBroadcastLocked(Intent intent) {
16007        // Refuse possible leaked file descriptors
16008        if (intent != null && intent.hasFileDescriptors() == true) {
16009            throw new IllegalArgumentException("File descriptors passed in Intent");
16010        }
16011
16012        int flags = intent.getFlags();
16013
16014        if (!mProcessesReady) {
16015            // if the caller really truly claims to know what they're doing, go
16016            // ahead and allow the broadcast without launching any receivers
16017            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16018                intent = new Intent(intent);
16019                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16020            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16021                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16022                        + " before boot completion");
16023                throw new IllegalStateException("Cannot broadcast before boot completed");
16024            }
16025        }
16026
16027        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16028            throw new IllegalArgumentException(
16029                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16030        }
16031
16032        return intent;
16033    }
16034
16035    public final int broadcastIntent(IApplicationThread caller,
16036            Intent intent, String resolvedType, IIntentReceiver resultTo,
16037            int resultCode, String resultData, Bundle map,
16038            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16039        enforceNotIsolatedCaller("broadcastIntent");
16040        synchronized(this) {
16041            intent = verifyBroadcastLocked(intent);
16042
16043            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16044            final int callingPid = Binder.getCallingPid();
16045            final int callingUid = Binder.getCallingUid();
16046            final long origId = Binder.clearCallingIdentity();
16047            int res = broadcastIntentLocked(callerApp,
16048                    callerApp != null ? callerApp.info.packageName : null,
16049                    intent, resolvedType, resultTo,
16050                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16051                    callingPid, callingUid, userId);
16052            Binder.restoreCallingIdentity(origId);
16053            return res;
16054        }
16055    }
16056
16057    int broadcastIntentInPackage(String packageName, int uid,
16058            Intent intent, String resolvedType, IIntentReceiver resultTo,
16059            int resultCode, String resultData, Bundle map,
16060            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16061        synchronized(this) {
16062            intent = verifyBroadcastLocked(intent);
16063
16064            final long origId = Binder.clearCallingIdentity();
16065            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16066                    resultTo, resultCode, resultData, map, requiredPermission,
16067                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16068            Binder.restoreCallingIdentity(origId);
16069            return res;
16070        }
16071    }
16072
16073    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16074        // Refuse possible leaked file descriptors
16075        if (intent != null && intent.hasFileDescriptors() == true) {
16076            throw new IllegalArgumentException("File descriptors passed in Intent");
16077        }
16078
16079        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16080                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16081
16082        synchronized(this) {
16083            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16084                    != PackageManager.PERMISSION_GRANTED) {
16085                String msg = "Permission Denial: unbroadcastIntent() from pid="
16086                        + Binder.getCallingPid()
16087                        + ", uid=" + Binder.getCallingUid()
16088                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16089                Slog.w(TAG, msg);
16090                throw new SecurityException(msg);
16091            }
16092            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16093            if (stickies != null) {
16094                ArrayList<Intent> list = stickies.get(intent.getAction());
16095                if (list != null) {
16096                    int N = list.size();
16097                    int i;
16098                    for (i=0; i<N; i++) {
16099                        if (intent.filterEquals(list.get(i))) {
16100                            list.remove(i);
16101                            break;
16102                        }
16103                    }
16104                    if (list.size() <= 0) {
16105                        stickies.remove(intent.getAction());
16106                    }
16107                }
16108                if (stickies.size() <= 0) {
16109                    mStickyBroadcasts.remove(userId);
16110                }
16111            }
16112        }
16113    }
16114
16115    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16116            String resultData, Bundle resultExtras, boolean resultAbort) {
16117        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16118        if (r == null) {
16119            Slog.w(TAG, "finishReceiver called but not found on queue");
16120            return false;
16121        }
16122
16123        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16124    }
16125
16126    void backgroundServicesFinishedLocked(int userId) {
16127        for (BroadcastQueue queue : mBroadcastQueues) {
16128            queue.backgroundServicesFinishedLocked(userId);
16129        }
16130    }
16131
16132    public void finishReceiver(IBinder who, int resultCode, String resultData,
16133            Bundle resultExtras, boolean resultAbort) {
16134        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16135
16136        // Refuse possible leaked file descriptors
16137        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16138            throw new IllegalArgumentException("File descriptors passed in Bundle");
16139        }
16140
16141        final long origId = Binder.clearCallingIdentity();
16142        try {
16143            boolean doNext = false;
16144            BroadcastRecord r;
16145
16146            synchronized(this) {
16147                r = broadcastRecordForReceiverLocked(who);
16148                if (r != null) {
16149                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16150                        resultData, resultExtras, resultAbort, true);
16151                }
16152            }
16153
16154            if (doNext) {
16155                r.queue.processNextBroadcast(false);
16156            }
16157            trimApplications();
16158        } finally {
16159            Binder.restoreCallingIdentity(origId);
16160        }
16161    }
16162
16163    // =========================================================
16164    // INSTRUMENTATION
16165    // =========================================================
16166
16167    public boolean startInstrumentation(ComponentName className,
16168            String profileFile, int flags, Bundle arguments,
16169            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16170            int userId, String abiOverride) {
16171        enforceNotIsolatedCaller("startInstrumentation");
16172        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16173                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16174        // Refuse possible leaked file descriptors
16175        if (arguments != null && arguments.hasFileDescriptors()) {
16176            throw new IllegalArgumentException("File descriptors passed in Bundle");
16177        }
16178
16179        synchronized(this) {
16180            InstrumentationInfo ii = null;
16181            ApplicationInfo ai = null;
16182            try {
16183                ii = mContext.getPackageManager().getInstrumentationInfo(
16184                    className, STOCK_PM_FLAGS);
16185                ai = AppGlobals.getPackageManager().getApplicationInfo(
16186                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16187            } catch (PackageManager.NameNotFoundException e) {
16188            } catch (RemoteException e) {
16189            }
16190            if (ii == null) {
16191                reportStartInstrumentationFailure(watcher, className,
16192                        "Unable to find instrumentation info for: " + className);
16193                return false;
16194            }
16195            if (ai == null) {
16196                reportStartInstrumentationFailure(watcher, className,
16197                        "Unable to find instrumentation target package: " + ii.targetPackage);
16198                return false;
16199            }
16200
16201            int match = mContext.getPackageManager().checkSignatures(
16202                    ii.targetPackage, ii.packageName);
16203            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16204                String msg = "Permission Denial: starting instrumentation "
16205                        + className + " from pid="
16206                        + Binder.getCallingPid()
16207                        + ", uid=" + Binder.getCallingPid()
16208                        + " not allowed because package " + ii.packageName
16209                        + " does not have a signature matching the target "
16210                        + ii.targetPackage;
16211                reportStartInstrumentationFailure(watcher, className, msg);
16212                throw new SecurityException(msg);
16213            }
16214
16215            final long origId = Binder.clearCallingIdentity();
16216            // Instrumentation can kill and relaunch even persistent processes
16217            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16218                    "start instr");
16219            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16220            app.instrumentationClass = className;
16221            app.instrumentationInfo = ai;
16222            app.instrumentationProfileFile = profileFile;
16223            app.instrumentationArguments = arguments;
16224            app.instrumentationWatcher = watcher;
16225            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16226            app.instrumentationResultClass = className;
16227            Binder.restoreCallingIdentity(origId);
16228        }
16229
16230        return true;
16231    }
16232
16233    /**
16234     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16235     * error to the logs, but if somebody is watching, send the report there too.  This enables
16236     * the "am" command to report errors with more information.
16237     *
16238     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16239     * @param cn The component name of the instrumentation.
16240     * @param report The error report.
16241     */
16242    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16243            ComponentName cn, String report) {
16244        Slog.w(TAG, report);
16245        try {
16246            if (watcher != null) {
16247                Bundle results = new Bundle();
16248                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16249                results.putString("Error", report);
16250                watcher.instrumentationStatus(cn, -1, results);
16251            }
16252        } catch (RemoteException e) {
16253            Slog.w(TAG, e);
16254        }
16255    }
16256
16257    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16258        if (app.instrumentationWatcher != null) {
16259            try {
16260                // NOTE:  IInstrumentationWatcher *must* be oneway here
16261                app.instrumentationWatcher.instrumentationFinished(
16262                    app.instrumentationClass,
16263                    resultCode,
16264                    results);
16265            } catch (RemoteException e) {
16266            }
16267        }
16268        if (app.instrumentationUiAutomationConnection != null) {
16269            try {
16270                app.instrumentationUiAutomationConnection.shutdown();
16271            } catch (RemoteException re) {
16272                /* ignore */
16273            }
16274            // Only a UiAutomation can set this flag and now that
16275            // it is finished we make sure it is reset to its default.
16276            mUserIsMonkey = false;
16277        }
16278        app.instrumentationWatcher = null;
16279        app.instrumentationUiAutomationConnection = null;
16280        app.instrumentationClass = null;
16281        app.instrumentationInfo = null;
16282        app.instrumentationProfileFile = null;
16283        app.instrumentationArguments = null;
16284
16285        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16286                "finished inst");
16287    }
16288
16289    public void finishInstrumentation(IApplicationThread target,
16290            int resultCode, Bundle results) {
16291        int userId = UserHandle.getCallingUserId();
16292        // Refuse possible leaked file descriptors
16293        if (results != null && results.hasFileDescriptors()) {
16294            throw new IllegalArgumentException("File descriptors passed in Intent");
16295        }
16296
16297        synchronized(this) {
16298            ProcessRecord app = getRecordForAppLocked(target);
16299            if (app == null) {
16300                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16301                return;
16302            }
16303            final long origId = Binder.clearCallingIdentity();
16304            finishInstrumentationLocked(app, resultCode, results);
16305            Binder.restoreCallingIdentity(origId);
16306        }
16307    }
16308
16309    // =========================================================
16310    // CONFIGURATION
16311    // =========================================================
16312
16313    public ConfigurationInfo getDeviceConfigurationInfo() {
16314        ConfigurationInfo config = new ConfigurationInfo();
16315        synchronized (this) {
16316            config.reqTouchScreen = mConfiguration.touchscreen;
16317            config.reqKeyboardType = mConfiguration.keyboard;
16318            config.reqNavigation = mConfiguration.navigation;
16319            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16320                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16321                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16322            }
16323            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16324                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16325                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16326            }
16327            config.reqGlEsVersion = GL_ES_VERSION;
16328        }
16329        return config;
16330    }
16331
16332    ActivityStack getFocusedStack() {
16333        return mStackSupervisor.getFocusedStack();
16334    }
16335
16336    public Configuration getConfiguration() {
16337        Configuration ci;
16338        synchronized(this) {
16339            ci = new Configuration(mConfiguration);
16340        }
16341        return ci;
16342    }
16343
16344    public void updatePersistentConfiguration(Configuration values) {
16345        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16346                "updateConfiguration()");
16347        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16348                "updateConfiguration()");
16349        if (values == null) {
16350            throw new NullPointerException("Configuration must not be null");
16351        }
16352
16353        synchronized(this) {
16354            final long origId = Binder.clearCallingIdentity();
16355            updateConfigurationLocked(values, null, true, false);
16356            Binder.restoreCallingIdentity(origId);
16357        }
16358    }
16359
16360    public void updateConfiguration(Configuration values) {
16361        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16362                "updateConfiguration()");
16363
16364        synchronized(this) {
16365            if (values == null && mWindowManager != null) {
16366                // sentinel: fetch the current configuration from the window manager
16367                values = mWindowManager.computeNewConfiguration();
16368            }
16369
16370            if (mWindowManager != null) {
16371                mProcessList.applyDisplaySize(mWindowManager);
16372            }
16373
16374            final long origId = Binder.clearCallingIdentity();
16375            if (values != null) {
16376                Settings.System.clearConfiguration(values);
16377            }
16378            updateConfigurationLocked(values, null, false, false);
16379            Binder.restoreCallingIdentity(origId);
16380        }
16381    }
16382
16383    /**
16384     * Do either or both things: (1) change the current configuration, and (2)
16385     * make sure the given activity is running with the (now) current
16386     * configuration.  Returns true if the activity has been left running, or
16387     * false if <var>starting</var> is being destroyed to match the new
16388     * configuration.
16389     * @param persistent TODO
16390     */
16391    boolean updateConfigurationLocked(Configuration values,
16392            ActivityRecord starting, boolean persistent, boolean initLocale) {
16393        int changes = 0;
16394
16395        if (values != null) {
16396            Configuration newConfig = new Configuration(mConfiguration);
16397            changes = newConfig.updateFrom(values);
16398            if (changes != 0) {
16399                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16400                    Slog.i(TAG, "Updating configuration to: " + values);
16401                }
16402
16403                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16404
16405                if (values.locale != null && !initLocale) {
16406                    saveLocaleLocked(values.locale,
16407                                     !values.locale.equals(mConfiguration.locale),
16408                                     values.userSetLocale);
16409                }
16410
16411                mConfigurationSeq++;
16412                if (mConfigurationSeq <= 0) {
16413                    mConfigurationSeq = 1;
16414                }
16415                newConfig.seq = mConfigurationSeq;
16416                mConfiguration = newConfig;
16417                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16418                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16419                //mUsageStatsService.noteStartConfig(newConfig);
16420
16421                final Configuration configCopy = new Configuration(mConfiguration);
16422
16423                // TODO: If our config changes, should we auto dismiss any currently
16424                // showing dialogs?
16425                mShowDialogs = shouldShowDialogs(newConfig);
16426
16427                AttributeCache ac = AttributeCache.instance();
16428                if (ac != null) {
16429                    ac.updateConfiguration(configCopy);
16430                }
16431
16432                // Make sure all resources in our process are updated
16433                // right now, so that anyone who is going to retrieve
16434                // resource values after we return will be sure to get
16435                // the new ones.  This is especially important during
16436                // boot, where the first config change needs to guarantee
16437                // all resources have that config before following boot
16438                // code is executed.
16439                mSystemThread.applyConfigurationToResources(configCopy);
16440
16441                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16442                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16443                    msg.obj = new Configuration(configCopy);
16444                    mHandler.sendMessage(msg);
16445                }
16446
16447                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16448                    ProcessRecord app = mLruProcesses.get(i);
16449                    try {
16450                        if (app.thread != null) {
16451                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16452                                    + app.processName + " new config " + mConfiguration);
16453                            app.thread.scheduleConfigurationChanged(configCopy);
16454                        }
16455                    } catch (Exception e) {
16456                    }
16457                }
16458                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16459                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16460                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16461                        | Intent.FLAG_RECEIVER_FOREGROUND);
16462                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16463                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16464                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16465                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16466                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16467                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16468                    broadcastIntentLocked(null, null, intent,
16469                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16470                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16471                }
16472            }
16473        }
16474
16475        boolean kept = true;
16476        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16477        // mainStack is null during startup.
16478        if (mainStack != null) {
16479            if (changes != 0 && starting == null) {
16480                // If the configuration changed, and the caller is not already
16481                // in the process of starting an activity, then find the top
16482                // activity to check if its configuration needs to change.
16483                starting = mainStack.topRunningActivityLocked(null);
16484            }
16485
16486            if (starting != null) {
16487                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16488                // And we need to make sure at this point that all other activities
16489                // are made visible with the correct configuration.
16490                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16491            }
16492        }
16493
16494        if (values != null && mWindowManager != null) {
16495            mWindowManager.setNewConfiguration(mConfiguration);
16496        }
16497
16498        return kept;
16499    }
16500
16501    /**
16502     * Decide based on the configuration whether we should shouw the ANR,
16503     * crash, etc dialogs.  The idea is that if there is no affordnace to
16504     * press the on-screen buttons, we shouldn't show the dialog.
16505     *
16506     * A thought: SystemUI might also want to get told about this, the Power
16507     * dialog / global actions also might want different behaviors.
16508     */
16509    private static final boolean shouldShowDialogs(Configuration config) {
16510        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16511                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16512    }
16513
16514    /**
16515     * Save the locale.  You must be inside a synchronized (this) block.
16516     */
16517    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16518        if(isDiff) {
16519            SystemProperties.set("user.language", l.getLanguage());
16520            SystemProperties.set("user.region", l.getCountry());
16521        }
16522
16523        if(isPersist) {
16524            SystemProperties.set("persist.sys.language", l.getLanguage());
16525            SystemProperties.set("persist.sys.country", l.getCountry());
16526            SystemProperties.set("persist.sys.localevar", l.getVariant());
16527
16528            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16529        }
16530    }
16531
16532    @Override
16533    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16534        synchronized (this) {
16535            ActivityRecord srec = ActivityRecord.forToken(token);
16536            if (srec.task != null && srec.task.stack != null) {
16537                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16538            }
16539        }
16540        return false;
16541    }
16542
16543    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16544            Intent resultData) {
16545
16546        synchronized (this) {
16547            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16548            if (stack != null) {
16549                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16550            }
16551            return false;
16552        }
16553    }
16554
16555    public int getLaunchedFromUid(IBinder activityToken) {
16556        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16557        if (srec == null) {
16558            return -1;
16559        }
16560        return srec.launchedFromUid;
16561    }
16562
16563    public String getLaunchedFromPackage(IBinder activityToken) {
16564        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16565        if (srec == null) {
16566            return null;
16567        }
16568        return srec.launchedFromPackage;
16569    }
16570
16571    // =========================================================
16572    // LIFETIME MANAGEMENT
16573    // =========================================================
16574
16575    // Returns which broadcast queue the app is the current [or imminent] receiver
16576    // on, or 'null' if the app is not an active broadcast recipient.
16577    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16578        BroadcastRecord r = app.curReceiver;
16579        if (r != null) {
16580            return r.queue;
16581        }
16582
16583        // It's not the current receiver, but it might be starting up to become one
16584        synchronized (this) {
16585            for (BroadcastQueue queue : mBroadcastQueues) {
16586                r = queue.mPendingBroadcast;
16587                if (r != null && r.curApp == app) {
16588                    // found it; report which queue it's in
16589                    return queue;
16590                }
16591            }
16592        }
16593
16594        return null;
16595    }
16596
16597    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16598            boolean doingAll, long now) {
16599        if (mAdjSeq == app.adjSeq) {
16600            // This adjustment has already been computed.
16601            return app.curRawAdj;
16602        }
16603
16604        if (app.thread == null) {
16605            app.adjSeq = mAdjSeq;
16606            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16607            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16608            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16609        }
16610
16611        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16612        app.adjSource = null;
16613        app.adjTarget = null;
16614        app.empty = false;
16615        app.cached = false;
16616
16617        final int activitiesSize = app.activities.size();
16618
16619        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16620            // The max adjustment doesn't allow this app to be anything
16621            // below foreground, so it is not worth doing work for it.
16622            app.adjType = "fixed";
16623            app.adjSeq = mAdjSeq;
16624            app.curRawAdj = app.maxAdj;
16625            app.foregroundActivities = false;
16626            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16627            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16628            // System processes can do UI, and when they do we want to have
16629            // them trim their memory after the user leaves the UI.  To
16630            // facilitate this, here we need to determine whether or not it
16631            // is currently showing UI.
16632            app.systemNoUi = true;
16633            if (app == TOP_APP) {
16634                app.systemNoUi = false;
16635            } else if (activitiesSize > 0) {
16636                for (int j = 0; j < activitiesSize; j++) {
16637                    final ActivityRecord r = app.activities.get(j);
16638                    if (r.visible) {
16639                        app.systemNoUi = false;
16640                    }
16641                }
16642            }
16643            if (!app.systemNoUi) {
16644                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16645            }
16646            return (app.curAdj=app.maxAdj);
16647        }
16648
16649        app.systemNoUi = false;
16650
16651        // Determine the importance of the process, starting with most
16652        // important to least, and assign an appropriate OOM adjustment.
16653        int adj;
16654        int schedGroup;
16655        int procState;
16656        boolean foregroundActivities = false;
16657        BroadcastQueue queue;
16658        if (app == TOP_APP) {
16659            // The last app on the list is the foreground app.
16660            adj = ProcessList.FOREGROUND_APP_ADJ;
16661            schedGroup = Process.THREAD_GROUP_DEFAULT;
16662            app.adjType = "top-activity";
16663            foregroundActivities = true;
16664            procState = ActivityManager.PROCESS_STATE_TOP;
16665        } else if (app.instrumentationClass != null) {
16666            // Don't want to kill running instrumentation.
16667            adj = ProcessList.FOREGROUND_APP_ADJ;
16668            schedGroup = Process.THREAD_GROUP_DEFAULT;
16669            app.adjType = "instrumentation";
16670            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16671        } else if ((queue = isReceivingBroadcast(app)) != null) {
16672            // An app that is currently receiving a broadcast also
16673            // counts as being in the foreground for OOM killer purposes.
16674            // It's placed in a sched group based on the nature of the
16675            // broadcast as reflected by which queue it's active in.
16676            adj = ProcessList.FOREGROUND_APP_ADJ;
16677            schedGroup = (queue == mFgBroadcastQueue)
16678                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16679            app.adjType = "broadcast";
16680            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16681        } else if (app.executingServices.size() > 0) {
16682            // An app that is currently executing a service callback also
16683            // counts as being in the foreground.
16684            adj = ProcessList.FOREGROUND_APP_ADJ;
16685            schedGroup = app.execServicesFg ?
16686                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16687            app.adjType = "exec-service";
16688            procState = ActivityManager.PROCESS_STATE_SERVICE;
16689            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16690        } else {
16691            // As far as we know the process is empty.  We may change our mind later.
16692            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16693            // At this point we don't actually know the adjustment.  Use the cached adj
16694            // value that the caller wants us to.
16695            adj = cachedAdj;
16696            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16697            app.cached = true;
16698            app.empty = true;
16699            app.adjType = "cch-empty";
16700        }
16701
16702        // Examine all activities if not already foreground.
16703        if (!foregroundActivities && activitiesSize > 0) {
16704            for (int j = 0; j < activitiesSize; j++) {
16705                final ActivityRecord r = app.activities.get(j);
16706                if (r.app != app) {
16707                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16708                            + app + "?!?");
16709                    continue;
16710                }
16711                if (r.visible) {
16712                    // App has a visible activity; only upgrade adjustment.
16713                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16714                        adj = ProcessList.VISIBLE_APP_ADJ;
16715                        app.adjType = "visible";
16716                    }
16717                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16718                        procState = ActivityManager.PROCESS_STATE_TOP;
16719                    }
16720                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16721                    app.cached = false;
16722                    app.empty = false;
16723                    foregroundActivities = true;
16724                    break;
16725                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16726                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16727                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16728                        app.adjType = "pausing";
16729                    }
16730                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16731                        procState = ActivityManager.PROCESS_STATE_TOP;
16732                    }
16733                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16734                    app.cached = false;
16735                    app.empty = false;
16736                    foregroundActivities = true;
16737                } else if (r.state == ActivityState.STOPPING) {
16738                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16739                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16740                        app.adjType = "stopping";
16741                    }
16742                    // For the process state, we will at this point consider the
16743                    // process to be cached.  It will be cached either as an activity
16744                    // or empty depending on whether the activity is finishing.  We do
16745                    // this so that we can treat the process as cached for purposes of
16746                    // memory trimming (determing current memory level, trim command to
16747                    // send to process) since there can be an arbitrary number of stopping
16748                    // processes and they should soon all go into the cached state.
16749                    if (!r.finishing) {
16750                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16751                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16752                        }
16753                    }
16754                    app.cached = false;
16755                    app.empty = false;
16756                    foregroundActivities = true;
16757                } else {
16758                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16759                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16760                        app.adjType = "cch-act";
16761                    }
16762                }
16763            }
16764        }
16765
16766        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16767            if (app.foregroundServices) {
16768                // The user is aware of this app, so make it visible.
16769                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16770                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16771                app.cached = false;
16772                app.adjType = "fg-service";
16773                schedGroup = Process.THREAD_GROUP_DEFAULT;
16774            } else if (app.forcingToForeground != null) {
16775                // The user is aware of this app, so make it visible.
16776                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16777                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16778                app.cached = false;
16779                app.adjType = "force-fg";
16780                app.adjSource = app.forcingToForeground;
16781                schedGroup = Process.THREAD_GROUP_DEFAULT;
16782            }
16783        }
16784
16785        if (app == mHeavyWeightProcess) {
16786            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16787                // We don't want to kill the current heavy-weight process.
16788                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16789                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16790                app.cached = false;
16791                app.adjType = "heavy";
16792            }
16793            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16794                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16795            }
16796        }
16797
16798        if (app == mHomeProcess) {
16799            if (adj > ProcessList.HOME_APP_ADJ) {
16800                // This process is hosting what we currently consider to be the
16801                // home app, so we don't want to let it go into the background.
16802                adj = ProcessList.HOME_APP_ADJ;
16803                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16804                app.cached = false;
16805                app.adjType = "home";
16806            }
16807            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16808                procState = ActivityManager.PROCESS_STATE_HOME;
16809            }
16810        }
16811
16812        if (app == mPreviousProcess && app.activities.size() > 0) {
16813            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16814                // This was the previous process that showed UI to the user.
16815                // We want to try to keep it around more aggressively, to give
16816                // a good experience around switching between two apps.
16817                adj = ProcessList.PREVIOUS_APP_ADJ;
16818                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16819                app.cached = false;
16820                app.adjType = "previous";
16821            }
16822            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16823                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16824            }
16825        }
16826
16827        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16828                + " reason=" + app.adjType);
16829
16830        // By default, we use the computed adjustment.  It may be changed if
16831        // there are applications dependent on our services or providers, but
16832        // this gives us a baseline and makes sure we don't get into an
16833        // infinite recursion.
16834        app.adjSeq = mAdjSeq;
16835        app.curRawAdj = adj;
16836        app.hasStartedServices = false;
16837
16838        if (mBackupTarget != null && app == mBackupTarget.app) {
16839            // If possible we want to avoid killing apps while they're being backed up
16840            if (adj > ProcessList.BACKUP_APP_ADJ) {
16841                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16842                adj = ProcessList.BACKUP_APP_ADJ;
16843                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16844                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16845                }
16846                app.adjType = "backup";
16847                app.cached = false;
16848            }
16849            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16850                procState = ActivityManager.PROCESS_STATE_BACKUP;
16851            }
16852        }
16853
16854        boolean mayBeTop = false;
16855
16856        for (int is = app.services.size()-1;
16857                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16858                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16859                        || procState > ActivityManager.PROCESS_STATE_TOP);
16860                is--) {
16861            ServiceRecord s = app.services.valueAt(is);
16862            if (s.startRequested) {
16863                app.hasStartedServices = true;
16864                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16865                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16866                }
16867                if (app.hasShownUi && app != mHomeProcess) {
16868                    // If this process has shown some UI, let it immediately
16869                    // go to the LRU list because it may be pretty heavy with
16870                    // UI stuff.  We'll tag it with a label just to help
16871                    // debug and understand what is going on.
16872                    if (adj > ProcessList.SERVICE_ADJ) {
16873                        app.adjType = "cch-started-ui-services";
16874                    }
16875                } else {
16876                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16877                        // This service has seen some activity within
16878                        // recent memory, so we will keep its process ahead
16879                        // of the background processes.
16880                        if (adj > ProcessList.SERVICE_ADJ) {
16881                            adj = ProcessList.SERVICE_ADJ;
16882                            app.adjType = "started-services";
16883                            app.cached = false;
16884                        }
16885                    }
16886                    // If we have let the service slide into the background
16887                    // state, still have some text describing what it is doing
16888                    // even though the service no longer has an impact.
16889                    if (adj > ProcessList.SERVICE_ADJ) {
16890                        app.adjType = "cch-started-services";
16891                    }
16892                }
16893            }
16894            for (int conni = s.connections.size()-1;
16895                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16896                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16897                            || procState > ActivityManager.PROCESS_STATE_TOP);
16898                    conni--) {
16899                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16900                for (int i = 0;
16901                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16902                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16903                                || procState > ActivityManager.PROCESS_STATE_TOP);
16904                        i++) {
16905                    // XXX should compute this based on the max of
16906                    // all connected clients.
16907                    ConnectionRecord cr = clist.get(i);
16908                    if (cr.binding.client == app) {
16909                        // Binding to ourself is not interesting.
16910                        continue;
16911                    }
16912                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16913                        ProcessRecord client = cr.binding.client;
16914                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16915                                TOP_APP, doingAll, now);
16916                        int clientProcState = client.curProcState;
16917                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16918                            // If the other app is cached for any reason, for purposes here
16919                            // we are going to consider it empty.  The specific cached state
16920                            // doesn't propagate except under certain conditions.
16921                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16922                        }
16923                        String adjType = null;
16924                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16925                            // Not doing bind OOM management, so treat
16926                            // this guy more like a started service.
16927                            if (app.hasShownUi && app != mHomeProcess) {
16928                                // If this process has shown some UI, let it immediately
16929                                // go to the LRU list because it may be pretty heavy with
16930                                // UI stuff.  We'll tag it with a label just to help
16931                                // debug and understand what is going on.
16932                                if (adj > clientAdj) {
16933                                    adjType = "cch-bound-ui-services";
16934                                }
16935                                app.cached = false;
16936                                clientAdj = adj;
16937                                clientProcState = procState;
16938                            } else {
16939                                if (now >= (s.lastActivity
16940                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16941                                    // This service has not seen activity within
16942                                    // recent memory, so allow it to drop to the
16943                                    // LRU list if there is no other reason to keep
16944                                    // it around.  We'll also tag it with a label just
16945                                    // to help debug and undertand what is going on.
16946                                    if (adj > clientAdj) {
16947                                        adjType = "cch-bound-services";
16948                                    }
16949                                    clientAdj = adj;
16950                                }
16951                            }
16952                        }
16953                        if (adj > clientAdj) {
16954                            // If this process has recently shown UI, and
16955                            // the process that is binding to it is less
16956                            // important than being visible, then we don't
16957                            // care about the binding as much as we care
16958                            // about letting this process get into the LRU
16959                            // list to be killed and restarted if needed for
16960                            // memory.
16961                            if (app.hasShownUi && app != mHomeProcess
16962                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16963                                adjType = "cch-bound-ui-services";
16964                            } else {
16965                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16966                                        |Context.BIND_IMPORTANT)) != 0) {
16967                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16968                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16969                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16970                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16971                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16972                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16973                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16974                                    adj = clientAdj;
16975                                } else {
16976                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16977                                        adj = ProcessList.VISIBLE_APP_ADJ;
16978                                    }
16979                                }
16980                                if (!client.cached) {
16981                                    app.cached = false;
16982                                }
16983                                adjType = "service";
16984                            }
16985                        }
16986                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16987                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16988                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16989                            }
16990                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16991                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16992                                    // Special handling of clients who are in the top state.
16993                                    // We *may* want to consider this process to be in the
16994                                    // top state as well, but only if there is not another
16995                                    // reason for it to be running.  Being on the top is a
16996                                    // special state, meaning you are specifically running
16997                                    // for the current top app.  If the process is already
16998                                    // running in the background for some other reason, it
16999                                    // is more important to continue considering it to be
17000                                    // in the background state.
17001                                    mayBeTop = true;
17002                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17003                                } else {
17004                                    // Special handling for above-top states (persistent
17005                                    // processes).  These should not bring the current process
17006                                    // into the top state, since they are not on top.  Instead
17007                                    // give them the best state after that.
17008                                    clientProcState =
17009                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17010                                }
17011                            }
17012                        } else {
17013                            if (clientProcState <
17014                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17015                                clientProcState =
17016                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17017                            }
17018                        }
17019                        if (procState > clientProcState) {
17020                            procState = clientProcState;
17021                        }
17022                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17023                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17024                            app.pendingUiClean = true;
17025                        }
17026                        if (adjType != null) {
17027                            app.adjType = adjType;
17028                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17029                                    .REASON_SERVICE_IN_USE;
17030                            app.adjSource = cr.binding.client;
17031                            app.adjSourceProcState = clientProcState;
17032                            app.adjTarget = s.name;
17033                        }
17034                    }
17035                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17036                        app.treatLikeActivity = true;
17037                    }
17038                    final ActivityRecord a = cr.activity;
17039                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17040                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17041                                (a.visible || a.state == ActivityState.RESUMED
17042                                 || a.state == ActivityState.PAUSING)) {
17043                            adj = ProcessList.FOREGROUND_APP_ADJ;
17044                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17045                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17046                            }
17047                            app.cached = false;
17048                            app.adjType = "service";
17049                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17050                                    .REASON_SERVICE_IN_USE;
17051                            app.adjSource = a;
17052                            app.adjSourceProcState = procState;
17053                            app.adjTarget = s.name;
17054                        }
17055                    }
17056                }
17057            }
17058        }
17059
17060        for (int provi = app.pubProviders.size()-1;
17061                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17062                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17063                        || procState > ActivityManager.PROCESS_STATE_TOP);
17064                provi--) {
17065            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17066            for (int i = cpr.connections.size()-1;
17067                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17068                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17069                            || procState > ActivityManager.PROCESS_STATE_TOP);
17070                    i--) {
17071                ContentProviderConnection conn = cpr.connections.get(i);
17072                ProcessRecord client = conn.client;
17073                if (client == app) {
17074                    // Being our own client is not interesting.
17075                    continue;
17076                }
17077                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17078                int clientProcState = client.curProcState;
17079                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17080                    // If the other app is cached for any reason, for purposes here
17081                    // we are going to consider it empty.
17082                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17083                }
17084                if (adj > clientAdj) {
17085                    if (app.hasShownUi && app != mHomeProcess
17086                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17087                        app.adjType = "cch-ui-provider";
17088                    } else {
17089                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17090                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17091                        app.adjType = "provider";
17092                    }
17093                    app.cached &= client.cached;
17094                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17095                            .REASON_PROVIDER_IN_USE;
17096                    app.adjSource = client;
17097                    app.adjSourceProcState = clientProcState;
17098                    app.adjTarget = cpr.name;
17099                }
17100                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17101                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17102                        // Special handling of clients who are in the top state.
17103                        // We *may* want to consider this process to be in the
17104                        // top state as well, but only if there is not another
17105                        // reason for it to be running.  Being on the top is a
17106                        // special state, meaning you are specifically running
17107                        // for the current top app.  If the process is already
17108                        // running in the background for some other reason, it
17109                        // is more important to continue considering it to be
17110                        // in the background state.
17111                        mayBeTop = true;
17112                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17113                    } else {
17114                        // Special handling for above-top states (persistent
17115                        // processes).  These should not bring the current process
17116                        // into the top state, since they are not on top.  Instead
17117                        // give them the best state after that.
17118                        clientProcState =
17119                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17120                    }
17121                }
17122                if (procState > clientProcState) {
17123                    procState = clientProcState;
17124                }
17125                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17126                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17127                }
17128            }
17129            // If the provider has external (non-framework) process
17130            // dependencies, ensure that its adjustment is at least
17131            // FOREGROUND_APP_ADJ.
17132            if (cpr.hasExternalProcessHandles()) {
17133                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17134                    adj = ProcessList.FOREGROUND_APP_ADJ;
17135                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17136                    app.cached = false;
17137                    app.adjType = "provider";
17138                    app.adjTarget = cpr.name;
17139                }
17140                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17141                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17142                }
17143            }
17144        }
17145
17146        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17147            // A client of one of our services or providers is in the top state.  We
17148            // *may* want to be in the top state, but not if we are already running in
17149            // the background for some other reason.  For the decision here, we are going
17150            // to pick out a few specific states that we want to remain in when a client
17151            // is top (states that tend to be longer-term) and otherwise allow it to go
17152            // to the top state.
17153            switch (procState) {
17154                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17155                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17156                case ActivityManager.PROCESS_STATE_SERVICE:
17157                    // These all are longer-term states, so pull them up to the top
17158                    // of the background states, but not all the way to the top state.
17159                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17160                    break;
17161                default:
17162                    // Otherwise, top is a better choice, so take it.
17163                    procState = ActivityManager.PROCESS_STATE_TOP;
17164                    break;
17165            }
17166        }
17167
17168        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17169            if (app.hasClientActivities) {
17170                // This is a cached process, but with client activities.  Mark it so.
17171                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17172                app.adjType = "cch-client-act";
17173            } else if (app.treatLikeActivity) {
17174                // This is a cached process, but somebody wants us to treat it like it has
17175                // an activity, okay!
17176                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17177                app.adjType = "cch-as-act";
17178            }
17179        }
17180
17181        if (adj == ProcessList.SERVICE_ADJ) {
17182            if (doingAll) {
17183                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17184                mNewNumServiceProcs++;
17185                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17186                if (!app.serviceb) {
17187                    // This service isn't far enough down on the LRU list to
17188                    // normally be a B service, but if we are low on RAM and it
17189                    // is large we want to force it down since we would prefer to
17190                    // keep launcher over it.
17191                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17192                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17193                        app.serviceHighRam = true;
17194                        app.serviceb = true;
17195                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17196                    } else {
17197                        mNewNumAServiceProcs++;
17198                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17199                    }
17200                } else {
17201                    app.serviceHighRam = false;
17202                }
17203            }
17204            if (app.serviceb) {
17205                adj = ProcessList.SERVICE_B_ADJ;
17206            }
17207        }
17208
17209        app.curRawAdj = adj;
17210
17211        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17212        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17213        if (adj > app.maxAdj) {
17214            adj = app.maxAdj;
17215            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17216                schedGroup = Process.THREAD_GROUP_DEFAULT;
17217            }
17218        }
17219
17220        // Do final modification to adj.  Everything we do between here and applying
17221        // the final setAdj must be done in this function, because we will also use
17222        // it when computing the final cached adj later.  Note that we don't need to
17223        // worry about this for max adj above, since max adj will always be used to
17224        // keep it out of the cached vaues.
17225        app.curAdj = app.modifyRawOomAdj(adj);
17226        app.curSchedGroup = schedGroup;
17227        app.curProcState = procState;
17228        app.foregroundActivities = foregroundActivities;
17229
17230        return app.curRawAdj;
17231    }
17232
17233    /**
17234     * Schedule PSS collection of a process.
17235     */
17236    void requestPssLocked(ProcessRecord proc, int procState) {
17237        if (mPendingPssProcesses.contains(proc)) {
17238            return;
17239        }
17240        if (mPendingPssProcesses.size() == 0) {
17241            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17242        }
17243        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17244        proc.pssProcState = procState;
17245        mPendingPssProcesses.add(proc);
17246    }
17247
17248    /**
17249     * Schedule PSS collection of all processes.
17250     */
17251    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17252        if (!always) {
17253            if (now < (mLastFullPssTime +
17254                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17255                return;
17256            }
17257        }
17258        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17259        mLastFullPssTime = now;
17260        mFullPssPending = true;
17261        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17262        mPendingPssProcesses.clear();
17263        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17264            ProcessRecord app = mLruProcesses.get(i);
17265            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17266                app.pssProcState = app.setProcState;
17267                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17268                        isSleeping(), now);
17269                mPendingPssProcesses.add(app);
17270            }
17271        }
17272        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17273    }
17274
17275    /**
17276     * Ask a given process to GC right now.
17277     */
17278    final void performAppGcLocked(ProcessRecord app) {
17279        try {
17280            app.lastRequestedGc = SystemClock.uptimeMillis();
17281            if (app.thread != null) {
17282                if (app.reportLowMemory) {
17283                    app.reportLowMemory = false;
17284                    app.thread.scheduleLowMemory();
17285                } else {
17286                    app.thread.processInBackground();
17287                }
17288            }
17289        } catch (Exception e) {
17290            // whatever.
17291        }
17292    }
17293
17294    /**
17295     * Returns true if things are idle enough to perform GCs.
17296     */
17297    private final boolean canGcNowLocked() {
17298        boolean processingBroadcasts = false;
17299        for (BroadcastQueue q : mBroadcastQueues) {
17300            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17301                processingBroadcasts = true;
17302            }
17303        }
17304        return !processingBroadcasts
17305                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17306    }
17307
17308    /**
17309     * Perform GCs on all processes that are waiting for it, but only
17310     * if things are idle.
17311     */
17312    final void performAppGcsLocked() {
17313        final int N = mProcessesToGc.size();
17314        if (N <= 0) {
17315            return;
17316        }
17317        if (canGcNowLocked()) {
17318            while (mProcessesToGc.size() > 0) {
17319                ProcessRecord proc = mProcessesToGc.remove(0);
17320                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17321                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17322                            <= SystemClock.uptimeMillis()) {
17323                        // To avoid spamming the system, we will GC processes one
17324                        // at a time, waiting a few seconds between each.
17325                        performAppGcLocked(proc);
17326                        scheduleAppGcsLocked();
17327                        return;
17328                    } else {
17329                        // It hasn't been long enough since we last GCed this
17330                        // process...  put it in the list to wait for its time.
17331                        addProcessToGcListLocked(proc);
17332                        break;
17333                    }
17334                }
17335            }
17336
17337            scheduleAppGcsLocked();
17338        }
17339    }
17340
17341    /**
17342     * If all looks good, perform GCs on all processes waiting for them.
17343     */
17344    final void performAppGcsIfAppropriateLocked() {
17345        if (canGcNowLocked()) {
17346            performAppGcsLocked();
17347            return;
17348        }
17349        // Still not idle, wait some more.
17350        scheduleAppGcsLocked();
17351    }
17352
17353    /**
17354     * Schedule the execution of all pending app GCs.
17355     */
17356    final void scheduleAppGcsLocked() {
17357        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17358
17359        if (mProcessesToGc.size() > 0) {
17360            // Schedule a GC for the time to the next process.
17361            ProcessRecord proc = mProcessesToGc.get(0);
17362            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17363
17364            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17365            long now = SystemClock.uptimeMillis();
17366            if (when < (now+GC_TIMEOUT)) {
17367                when = now + GC_TIMEOUT;
17368            }
17369            mHandler.sendMessageAtTime(msg, when);
17370        }
17371    }
17372
17373    /**
17374     * Add a process to the array of processes waiting to be GCed.  Keeps the
17375     * list in sorted order by the last GC time.  The process can't already be
17376     * on the list.
17377     */
17378    final void addProcessToGcListLocked(ProcessRecord proc) {
17379        boolean added = false;
17380        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17381            if (mProcessesToGc.get(i).lastRequestedGc <
17382                    proc.lastRequestedGc) {
17383                added = true;
17384                mProcessesToGc.add(i+1, proc);
17385                break;
17386            }
17387        }
17388        if (!added) {
17389            mProcessesToGc.add(0, proc);
17390        }
17391    }
17392
17393    /**
17394     * Set up to ask a process to GC itself.  This will either do it
17395     * immediately, or put it on the list of processes to gc the next
17396     * time things are idle.
17397     */
17398    final void scheduleAppGcLocked(ProcessRecord app) {
17399        long now = SystemClock.uptimeMillis();
17400        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17401            return;
17402        }
17403        if (!mProcessesToGc.contains(app)) {
17404            addProcessToGcListLocked(app);
17405            scheduleAppGcsLocked();
17406        }
17407    }
17408
17409    final void checkExcessivePowerUsageLocked(boolean doKills) {
17410        updateCpuStatsNow();
17411
17412        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17413        boolean doWakeKills = doKills;
17414        boolean doCpuKills = doKills;
17415        if (mLastPowerCheckRealtime == 0) {
17416            doWakeKills = false;
17417        }
17418        if (mLastPowerCheckUptime == 0) {
17419            doCpuKills = false;
17420        }
17421        if (stats.isScreenOn()) {
17422            doWakeKills = false;
17423        }
17424        final long curRealtime = SystemClock.elapsedRealtime();
17425        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17426        final long curUptime = SystemClock.uptimeMillis();
17427        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17428        mLastPowerCheckRealtime = curRealtime;
17429        mLastPowerCheckUptime = curUptime;
17430        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17431            doWakeKills = false;
17432        }
17433        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17434            doCpuKills = false;
17435        }
17436        int i = mLruProcesses.size();
17437        while (i > 0) {
17438            i--;
17439            ProcessRecord app = mLruProcesses.get(i);
17440            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17441                long wtime;
17442                synchronized (stats) {
17443                    wtime = stats.getProcessWakeTime(app.info.uid,
17444                            app.pid, curRealtime);
17445                }
17446                long wtimeUsed = wtime - app.lastWakeTime;
17447                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17448                if (DEBUG_POWER) {
17449                    StringBuilder sb = new StringBuilder(128);
17450                    sb.append("Wake for ");
17451                    app.toShortString(sb);
17452                    sb.append(": over ");
17453                    TimeUtils.formatDuration(realtimeSince, sb);
17454                    sb.append(" used ");
17455                    TimeUtils.formatDuration(wtimeUsed, sb);
17456                    sb.append(" (");
17457                    sb.append((wtimeUsed*100)/realtimeSince);
17458                    sb.append("%)");
17459                    Slog.i(TAG, sb.toString());
17460                    sb.setLength(0);
17461                    sb.append("CPU for ");
17462                    app.toShortString(sb);
17463                    sb.append(": over ");
17464                    TimeUtils.formatDuration(uptimeSince, sb);
17465                    sb.append(" used ");
17466                    TimeUtils.formatDuration(cputimeUsed, sb);
17467                    sb.append(" (");
17468                    sb.append((cputimeUsed*100)/uptimeSince);
17469                    sb.append("%)");
17470                    Slog.i(TAG, sb.toString());
17471                }
17472                // If a process has held a wake lock for more
17473                // than 50% of the time during this period,
17474                // that sounds bad.  Kill!
17475                if (doWakeKills && realtimeSince > 0
17476                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17477                    synchronized (stats) {
17478                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17479                                realtimeSince, wtimeUsed);
17480                    }
17481                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17482                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17483                } else if (doCpuKills && uptimeSince > 0
17484                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17485                    synchronized (stats) {
17486                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17487                                uptimeSince, cputimeUsed);
17488                    }
17489                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17490                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17491                } else {
17492                    app.lastWakeTime = wtime;
17493                    app.lastCpuTime = app.curCpuTime;
17494                }
17495            }
17496        }
17497    }
17498
17499    private final boolean applyOomAdjLocked(ProcessRecord app,
17500            ProcessRecord TOP_APP, boolean doingAll, long now) {
17501        boolean success = true;
17502
17503        if (app.curRawAdj != app.setRawAdj) {
17504            app.setRawAdj = app.curRawAdj;
17505        }
17506
17507        int changes = 0;
17508
17509        if (app.curAdj != app.setAdj) {
17510            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17511            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17512                TAG, "Set " + app.pid + " " + app.processName +
17513                " adj " + app.curAdj + ": " + app.adjType);
17514            app.setAdj = app.curAdj;
17515        }
17516
17517        if (app.setSchedGroup != app.curSchedGroup) {
17518            app.setSchedGroup = app.curSchedGroup;
17519            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17520                    "Setting process group of " + app.processName
17521                    + " to " + app.curSchedGroup);
17522            if (app.waitingToKill != null &&
17523                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17524                app.kill(app.waitingToKill, true);
17525                success = false;
17526            } else {
17527                if (true) {
17528                    long oldId = Binder.clearCallingIdentity();
17529                    try {
17530                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17531                    } catch (Exception e) {
17532                        Slog.w(TAG, "Failed setting process group of " + app.pid
17533                                + " to " + app.curSchedGroup);
17534                        e.printStackTrace();
17535                    } finally {
17536                        Binder.restoreCallingIdentity(oldId);
17537                    }
17538                } else {
17539                    if (app.thread != null) {
17540                        try {
17541                            app.thread.setSchedulingGroup(app.curSchedGroup);
17542                        } catch (RemoteException e) {
17543                        }
17544                    }
17545                }
17546                Process.setSwappiness(app.pid,
17547                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17548            }
17549        }
17550        if (app.repForegroundActivities != app.foregroundActivities) {
17551            app.repForegroundActivities = app.foregroundActivities;
17552            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17553        }
17554        if (app.repProcState != app.curProcState) {
17555            app.repProcState = app.curProcState;
17556            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17557            if (app.thread != null) {
17558                try {
17559                    if (false) {
17560                        //RuntimeException h = new RuntimeException("here");
17561                        Slog.i(TAG, "Sending new process state " + app.repProcState
17562                                + " to " + app /*, h*/);
17563                    }
17564                    app.thread.setProcessState(app.repProcState);
17565                } catch (RemoteException e) {
17566                }
17567            }
17568        }
17569        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17570                app.setProcState)) {
17571            app.lastStateTime = now;
17572            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17573                    isSleeping(), now);
17574            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17575                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17576                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17577                    + (app.nextPssTime-now) + ": " + app);
17578        } else {
17579            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17580                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17581                requestPssLocked(app, app.setProcState);
17582                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17583                        isSleeping(), now);
17584            } else if (false && DEBUG_PSS) {
17585                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17586            }
17587        }
17588        if (app.setProcState != app.curProcState) {
17589            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17590                    "Proc state change of " + app.processName
17591                    + " to " + app.curProcState);
17592            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17593            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17594            if (setImportant && !curImportant) {
17595                // This app is no longer something we consider important enough to allow to
17596                // use arbitrary amounts of battery power.  Note
17597                // its current wake lock time to later know to kill it if
17598                // it is not behaving well.
17599                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17600                synchronized (stats) {
17601                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17602                            app.pid, SystemClock.elapsedRealtime());
17603                }
17604                app.lastCpuTime = app.curCpuTime;
17605
17606            }
17607            app.setProcState = app.curProcState;
17608            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17609                app.notCachedSinceIdle = false;
17610            }
17611            if (!doingAll) {
17612                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17613            } else {
17614                app.procStateChanged = true;
17615            }
17616        }
17617
17618        if (changes != 0) {
17619            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17620            int i = mPendingProcessChanges.size()-1;
17621            ProcessChangeItem item = null;
17622            while (i >= 0) {
17623                item = mPendingProcessChanges.get(i);
17624                if (item.pid == app.pid) {
17625                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17626                    break;
17627                }
17628                i--;
17629            }
17630            if (i < 0) {
17631                // No existing item in pending changes; need a new one.
17632                final int NA = mAvailProcessChanges.size();
17633                if (NA > 0) {
17634                    item = mAvailProcessChanges.remove(NA-1);
17635                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17636                } else {
17637                    item = new ProcessChangeItem();
17638                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17639                }
17640                item.changes = 0;
17641                item.pid = app.pid;
17642                item.uid = app.info.uid;
17643                if (mPendingProcessChanges.size() == 0) {
17644                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17645                            "*** Enqueueing dispatch processes changed!");
17646                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17647                }
17648                mPendingProcessChanges.add(item);
17649            }
17650            item.changes |= changes;
17651            item.processState = app.repProcState;
17652            item.foregroundActivities = app.repForegroundActivities;
17653            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17654                    + Integer.toHexString(System.identityHashCode(item))
17655                    + " " + app.toShortString() + ": changes=" + item.changes
17656                    + " procState=" + item.processState
17657                    + " foreground=" + item.foregroundActivities
17658                    + " type=" + app.adjType + " source=" + app.adjSource
17659                    + " target=" + app.adjTarget);
17660        }
17661
17662        return success;
17663    }
17664
17665    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17666        if (proc.thread != null) {
17667            if (proc.baseProcessTracker != null) {
17668                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17669            }
17670            if (proc.repProcState >= 0) {
17671                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17672                        proc.repProcState);
17673            }
17674        }
17675    }
17676
17677    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17678            ProcessRecord TOP_APP, boolean doingAll, long now) {
17679        if (app.thread == null) {
17680            return false;
17681        }
17682
17683        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17684
17685        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17686    }
17687
17688    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17689            boolean oomAdj) {
17690        if (isForeground != proc.foregroundServices) {
17691            proc.foregroundServices = isForeground;
17692            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17693                    proc.info.uid);
17694            if (isForeground) {
17695                if (curProcs == null) {
17696                    curProcs = new ArrayList<ProcessRecord>();
17697                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17698                }
17699                if (!curProcs.contains(proc)) {
17700                    curProcs.add(proc);
17701                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17702                            proc.info.packageName, proc.info.uid);
17703                }
17704            } else {
17705                if (curProcs != null) {
17706                    if (curProcs.remove(proc)) {
17707                        mBatteryStatsService.noteEvent(
17708                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17709                                proc.info.packageName, proc.info.uid);
17710                        if (curProcs.size() <= 0) {
17711                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17712                        }
17713                    }
17714                }
17715            }
17716            if (oomAdj) {
17717                updateOomAdjLocked();
17718            }
17719        }
17720    }
17721
17722    private final ActivityRecord resumedAppLocked() {
17723        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17724        String pkg;
17725        int uid;
17726        if (act != null) {
17727            pkg = act.packageName;
17728            uid = act.info.applicationInfo.uid;
17729        } else {
17730            pkg = null;
17731            uid = -1;
17732        }
17733        // Has the UID or resumed package name changed?
17734        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17735                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17736            if (mCurResumedPackage != null) {
17737                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17738                        mCurResumedPackage, mCurResumedUid);
17739            }
17740            mCurResumedPackage = pkg;
17741            mCurResumedUid = uid;
17742            if (mCurResumedPackage != null) {
17743                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17744                        mCurResumedPackage, mCurResumedUid);
17745            }
17746        }
17747        return act;
17748    }
17749
17750    final boolean updateOomAdjLocked(ProcessRecord app) {
17751        final ActivityRecord TOP_ACT = resumedAppLocked();
17752        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17753        final boolean wasCached = app.cached;
17754
17755        mAdjSeq++;
17756
17757        // This is the desired cached adjusment we want to tell it to use.
17758        // If our app is currently cached, we know it, and that is it.  Otherwise,
17759        // we don't know it yet, and it needs to now be cached we will then
17760        // need to do a complete oom adj.
17761        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17762                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17763        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17764                SystemClock.uptimeMillis());
17765        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17766            // Changed to/from cached state, so apps after it in the LRU
17767            // list may also be changed.
17768            updateOomAdjLocked();
17769        }
17770        return success;
17771    }
17772
17773    final void updateOomAdjLocked() {
17774        final ActivityRecord TOP_ACT = resumedAppLocked();
17775        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17776        final long now = SystemClock.uptimeMillis();
17777        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17778        final int N = mLruProcesses.size();
17779
17780        if (false) {
17781            RuntimeException e = new RuntimeException();
17782            e.fillInStackTrace();
17783            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17784        }
17785
17786        mAdjSeq++;
17787        mNewNumServiceProcs = 0;
17788        mNewNumAServiceProcs = 0;
17789
17790        final int emptyProcessLimit;
17791        final int cachedProcessLimit;
17792        if (mProcessLimit <= 0) {
17793            emptyProcessLimit = cachedProcessLimit = 0;
17794        } else if (mProcessLimit == 1) {
17795            emptyProcessLimit = 1;
17796            cachedProcessLimit = 0;
17797        } else {
17798            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17799            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17800        }
17801
17802        // Let's determine how many processes we have running vs.
17803        // how many slots we have for background processes; we may want
17804        // to put multiple processes in a slot of there are enough of
17805        // them.
17806        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17807                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17808        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17809        if (numEmptyProcs > cachedProcessLimit) {
17810            // If there are more empty processes than our limit on cached
17811            // processes, then use the cached process limit for the factor.
17812            // This ensures that the really old empty processes get pushed
17813            // down to the bottom, so if we are running low on memory we will
17814            // have a better chance at keeping around more cached processes
17815            // instead of a gazillion empty processes.
17816            numEmptyProcs = cachedProcessLimit;
17817        }
17818        int emptyFactor = numEmptyProcs/numSlots;
17819        if (emptyFactor < 1) emptyFactor = 1;
17820        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17821        if (cachedFactor < 1) cachedFactor = 1;
17822        int stepCached = 0;
17823        int stepEmpty = 0;
17824        int numCached = 0;
17825        int numEmpty = 0;
17826        int numTrimming = 0;
17827
17828        mNumNonCachedProcs = 0;
17829        mNumCachedHiddenProcs = 0;
17830
17831        // First update the OOM adjustment for each of the
17832        // application processes based on their current state.
17833        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17834        int nextCachedAdj = curCachedAdj+1;
17835        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17836        int nextEmptyAdj = curEmptyAdj+2;
17837        for (int i=N-1; i>=0; i--) {
17838            ProcessRecord app = mLruProcesses.get(i);
17839            if (!app.killedByAm && app.thread != null) {
17840                app.procStateChanged = false;
17841                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17842
17843                // If we haven't yet assigned the final cached adj
17844                // to the process, do that now.
17845                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17846                    switch (app.curProcState) {
17847                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17848                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17849                            // This process is a cached process holding activities...
17850                            // assign it the next cached value for that type, and then
17851                            // step that cached level.
17852                            app.curRawAdj = curCachedAdj;
17853                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17854                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17855                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17856                                    + ")");
17857                            if (curCachedAdj != nextCachedAdj) {
17858                                stepCached++;
17859                                if (stepCached >= cachedFactor) {
17860                                    stepCached = 0;
17861                                    curCachedAdj = nextCachedAdj;
17862                                    nextCachedAdj += 2;
17863                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17864                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17865                                    }
17866                                }
17867                            }
17868                            break;
17869                        default:
17870                            // For everything else, assign next empty cached process
17871                            // level and bump that up.  Note that this means that
17872                            // long-running services that have dropped down to the
17873                            // cached level will be treated as empty (since their process
17874                            // state is still as a service), which is what we want.
17875                            app.curRawAdj = curEmptyAdj;
17876                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17877                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17878                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17879                                    + ")");
17880                            if (curEmptyAdj != nextEmptyAdj) {
17881                                stepEmpty++;
17882                                if (stepEmpty >= emptyFactor) {
17883                                    stepEmpty = 0;
17884                                    curEmptyAdj = nextEmptyAdj;
17885                                    nextEmptyAdj += 2;
17886                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17887                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17888                                    }
17889                                }
17890                            }
17891                            break;
17892                    }
17893                }
17894
17895                applyOomAdjLocked(app, TOP_APP, true, now);
17896
17897                // Count the number of process types.
17898                switch (app.curProcState) {
17899                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17900                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17901                        mNumCachedHiddenProcs++;
17902                        numCached++;
17903                        if (numCached > cachedProcessLimit) {
17904                            app.kill("cached #" + numCached, true);
17905                        }
17906                        break;
17907                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17908                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17909                                && app.lastActivityTime < oldTime) {
17910                            app.kill("empty for "
17911                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17912                                    / 1000) + "s", true);
17913                        } else {
17914                            numEmpty++;
17915                            if (numEmpty > emptyProcessLimit) {
17916                                app.kill("empty #" + numEmpty, true);
17917                            }
17918                        }
17919                        break;
17920                    default:
17921                        mNumNonCachedProcs++;
17922                        break;
17923                }
17924
17925                if (app.isolated && app.services.size() <= 0) {
17926                    // If this is an isolated process, and there are no
17927                    // services running in it, then the process is no longer
17928                    // needed.  We agressively kill these because we can by
17929                    // definition not re-use the same process again, and it is
17930                    // good to avoid having whatever code was running in them
17931                    // left sitting around after no longer needed.
17932                    app.kill("isolated not needed", true);
17933                }
17934
17935                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17936                        && !app.killedByAm) {
17937                    numTrimming++;
17938                }
17939            }
17940        }
17941
17942        mNumServiceProcs = mNewNumServiceProcs;
17943
17944        // Now determine the memory trimming level of background processes.
17945        // Unfortunately we need to start at the back of the list to do this
17946        // properly.  We only do this if the number of background apps we
17947        // are managing to keep around is less than half the maximum we desire;
17948        // if we are keeping a good number around, we'll let them use whatever
17949        // memory they want.
17950        final int numCachedAndEmpty = numCached + numEmpty;
17951        int memFactor;
17952        if (numCached <= ProcessList.TRIM_CACHED_APPS
17953                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17954            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17955                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17956            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17957                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17958            } else {
17959                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17960            }
17961        } else {
17962            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17963        }
17964        // We always allow the memory level to go up (better).  We only allow it to go
17965        // down if we are in a state where that is allowed, *and* the total number of processes
17966        // has gone down since last time.
17967        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17968                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17969                + " last=" + mLastNumProcesses);
17970        if (memFactor > mLastMemoryLevel) {
17971            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17972                memFactor = mLastMemoryLevel;
17973                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17974            }
17975        }
17976        mLastMemoryLevel = memFactor;
17977        mLastNumProcesses = mLruProcesses.size();
17978        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17979        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17980        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17981            if (mLowRamStartTime == 0) {
17982                mLowRamStartTime = now;
17983            }
17984            int step = 0;
17985            int fgTrimLevel;
17986            switch (memFactor) {
17987                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17988                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17989                    break;
17990                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17991                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17992                    break;
17993                default:
17994                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17995                    break;
17996            }
17997            int factor = numTrimming/3;
17998            int minFactor = 2;
17999            if (mHomeProcess != null) minFactor++;
18000            if (mPreviousProcess != null) minFactor++;
18001            if (factor < minFactor) factor = minFactor;
18002            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18003            for (int i=N-1; i>=0; i--) {
18004                ProcessRecord app = mLruProcesses.get(i);
18005                if (allChanged || app.procStateChanged) {
18006                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18007                    app.procStateChanged = false;
18008                }
18009                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18010                        && !app.killedByAm) {
18011                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18012                        try {
18013                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18014                                    "Trimming memory of " + app.processName
18015                                    + " to " + curLevel);
18016                            app.thread.scheduleTrimMemory(curLevel);
18017                        } catch (RemoteException e) {
18018                        }
18019                        if (false) {
18020                            // For now we won't do this; our memory trimming seems
18021                            // to be good enough at this point that destroying
18022                            // activities causes more harm than good.
18023                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18024                                    && app != mHomeProcess && app != mPreviousProcess) {
18025                                // Need to do this on its own message because the stack may not
18026                                // be in a consistent state at this point.
18027                                // For these apps we will also finish their activities
18028                                // to help them free memory.
18029                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18030                            }
18031                        }
18032                    }
18033                    app.trimMemoryLevel = curLevel;
18034                    step++;
18035                    if (step >= factor) {
18036                        step = 0;
18037                        switch (curLevel) {
18038                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18039                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18040                                break;
18041                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18042                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18043                                break;
18044                        }
18045                    }
18046                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18047                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18048                            && app.thread != null) {
18049                        try {
18050                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18051                                    "Trimming memory of heavy-weight " + app.processName
18052                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18053                            app.thread.scheduleTrimMemory(
18054                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18055                        } catch (RemoteException e) {
18056                        }
18057                    }
18058                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18059                } else {
18060                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18061                            || app.systemNoUi) && app.pendingUiClean) {
18062                        // If this application is now in the background and it
18063                        // had done UI, then give it the special trim level to
18064                        // have it free UI resources.
18065                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18066                        if (app.trimMemoryLevel < level && app.thread != null) {
18067                            try {
18068                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18069                                        "Trimming memory of bg-ui " + app.processName
18070                                        + " to " + level);
18071                                app.thread.scheduleTrimMemory(level);
18072                            } catch (RemoteException e) {
18073                            }
18074                        }
18075                        app.pendingUiClean = false;
18076                    }
18077                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18078                        try {
18079                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18080                                    "Trimming memory of fg " + app.processName
18081                                    + " to " + fgTrimLevel);
18082                            app.thread.scheduleTrimMemory(fgTrimLevel);
18083                        } catch (RemoteException e) {
18084                        }
18085                    }
18086                    app.trimMemoryLevel = fgTrimLevel;
18087                }
18088            }
18089        } else {
18090            if (mLowRamStartTime != 0) {
18091                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18092                mLowRamStartTime = 0;
18093            }
18094            for (int i=N-1; i>=0; i--) {
18095                ProcessRecord app = mLruProcesses.get(i);
18096                if (allChanged || app.procStateChanged) {
18097                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18098                    app.procStateChanged = false;
18099                }
18100                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18101                        || app.systemNoUi) && app.pendingUiClean) {
18102                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18103                            && app.thread != null) {
18104                        try {
18105                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18106                                    "Trimming memory of ui hidden " + app.processName
18107                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18108                            app.thread.scheduleTrimMemory(
18109                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18110                        } catch (RemoteException e) {
18111                        }
18112                    }
18113                    app.pendingUiClean = false;
18114                }
18115                app.trimMemoryLevel = 0;
18116            }
18117        }
18118
18119        if (mAlwaysFinishActivities) {
18120            // Need to do this on its own message because the stack may not
18121            // be in a consistent state at this point.
18122            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18123        }
18124
18125        if (allChanged) {
18126            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18127        }
18128
18129        if (mProcessStats.shouldWriteNowLocked(now)) {
18130            mHandler.post(new Runnable() {
18131                @Override public void run() {
18132                    synchronized (ActivityManagerService.this) {
18133                        mProcessStats.writeStateAsyncLocked();
18134                    }
18135                }
18136            });
18137        }
18138
18139        if (DEBUG_OOM_ADJ) {
18140            if (false) {
18141                RuntimeException here = new RuntimeException("here");
18142                here.fillInStackTrace();
18143                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18144            } else {
18145                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18146            }
18147        }
18148    }
18149
18150    final void trimApplications() {
18151        synchronized (this) {
18152            int i;
18153
18154            // First remove any unused application processes whose package
18155            // has been removed.
18156            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18157                final ProcessRecord app = mRemovedProcesses.get(i);
18158                if (app.activities.size() == 0
18159                        && app.curReceiver == null && app.services.size() == 0) {
18160                    Slog.i(
18161                        TAG, "Exiting empty application process "
18162                        + app.processName + " ("
18163                        + (app.thread != null ? app.thread.asBinder() : null)
18164                        + ")\n");
18165                    if (app.pid > 0 && app.pid != MY_PID) {
18166                        app.kill("empty", false);
18167                    } else {
18168                        try {
18169                            app.thread.scheduleExit();
18170                        } catch (Exception e) {
18171                            // Ignore exceptions.
18172                        }
18173                    }
18174                    cleanUpApplicationRecordLocked(app, false, true, -1);
18175                    mRemovedProcesses.remove(i);
18176
18177                    if (app.persistent) {
18178                        addAppLocked(app.info, false, null /* ABI override */);
18179                    }
18180                }
18181            }
18182
18183            // Now update the oom adj for all processes.
18184            updateOomAdjLocked();
18185        }
18186    }
18187
18188    /** This method sends the specified signal to each of the persistent apps */
18189    public void signalPersistentProcesses(int sig) throws RemoteException {
18190        if (sig != Process.SIGNAL_USR1) {
18191            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18192        }
18193
18194        synchronized (this) {
18195            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18196                    != PackageManager.PERMISSION_GRANTED) {
18197                throw new SecurityException("Requires permission "
18198                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18199            }
18200
18201            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18202                ProcessRecord r = mLruProcesses.get(i);
18203                if (r.thread != null && r.persistent) {
18204                    Process.sendSignal(r.pid, sig);
18205                }
18206            }
18207        }
18208    }
18209
18210    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18211        if (proc == null || proc == mProfileProc) {
18212            proc = mProfileProc;
18213            profileType = mProfileType;
18214            clearProfilerLocked();
18215        }
18216        if (proc == null) {
18217            return;
18218        }
18219        try {
18220            proc.thread.profilerControl(false, null, profileType);
18221        } catch (RemoteException e) {
18222            throw new IllegalStateException("Process disappeared");
18223        }
18224    }
18225
18226    private void clearProfilerLocked() {
18227        if (mProfileFd != null) {
18228            try {
18229                mProfileFd.close();
18230            } catch (IOException e) {
18231            }
18232        }
18233        mProfileApp = null;
18234        mProfileProc = null;
18235        mProfileFile = null;
18236        mProfileType = 0;
18237        mAutoStopProfiler = false;
18238        mSamplingInterval = 0;
18239    }
18240
18241    public boolean profileControl(String process, int userId, boolean start,
18242            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18243
18244        try {
18245            synchronized (this) {
18246                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18247                // its own permission.
18248                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18249                        != PackageManager.PERMISSION_GRANTED) {
18250                    throw new SecurityException("Requires permission "
18251                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18252                }
18253
18254                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18255                    throw new IllegalArgumentException("null profile info or fd");
18256                }
18257
18258                ProcessRecord proc = null;
18259                if (process != null) {
18260                    proc = findProcessLocked(process, userId, "profileControl");
18261                }
18262
18263                if (start && (proc == null || proc.thread == null)) {
18264                    throw new IllegalArgumentException("Unknown process: " + process);
18265                }
18266
18267                if (start) {
18268                    stopProfilerLocked(null, 0);
18269                    setProfileApp(proc.info, proc.processName, profilerInfo);
18270                    mProfileProc = proc;
18271                    mProfileType = profileType;
18272                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18273                    try {
18274                        fd = fd.dup();
18275                    } catch (IOException e) {
18276                        fd = null;
18277                    }
18278                    profilerInfo.profileFd = fd;
18279                    proc.thread.profilerControl(start, profilerInfo, profileType);
18280                    fd = null;
18281                    mProfileFd = null;
18282                } else {
18283                    stopProfilerLocked(proc, profileType);
18284                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18285                        try {
18286                            profilerInfo.profileFd.close();
18287                        } catch (IOException e) {
18288                        }
18289                    }
18290                }
18291
18292                return true;
18293            }
18294        } catch (RemoteException e) {
18295            throw new IllegalStateException("Process disappeared");
18296        } finally {
18297            if (profilerInfo != null && profilerInfo.profileFd != null) {
18298                try {
18299                    profilerInfo.profileFd.close();
18300                } catch (IOException e) {
18301                }
18302            }
18303        }
18304    }
18305
18306    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18307        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18308                userId, true, ALLOW_FULL_ONLY, callName, null);
18309        ProcessRecord proc = null;
18310        try {
18311            int pid = Integer.parseInt(process);
18312            synchronized (mPidsSelfLocked) {
18313                proc = mPidsSelfLocked.get(pid);
18314            }
18315        } catch (NumberFormatException e) {
18316        }
18317
18318        if (proc == null) {
18319            ArrayMap<String, SparseArray<ProcessRecord>> all
18320                    = mProcessNames.getMap();
18321            SparseArray<ProcessRecord> procs = all.get(process);
18322            if (procs != null && procs.size() > 0) {
18323                proc = procs.valueAt(0);
18324                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18325                    for (int i=1; i<procs.size(); i++) {
18326                        ProcessRecord thisProc = procs.valueAt(i);
18327                        if (thisProc.userId == userId) {
18328                            proc = thisProc;
18329                            break;
18330                        }
18331                    }
18332                }
18333            }
18334        }
18335
18336        return proc;
18337    }
18338
18339    public boolean dumpHeap(String process, int userId, boolean managed,
18340            String path, ParcelFileDescriptor fd) throws RemoteException {
18341
18342        try {
18343            synchronized (this) {
18344                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18345                // its own permission (same as profileControl).
18346                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18347                        != PackageManager.PERMISSION_GRANTED) {
18348                    throw new SecurityException("Requires permission "
18349                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18350                }
18351
18352                if (fd == null) {
18353                    throw new IllegalArgumentException("null fd");
18354                }
18355
18356                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18357                if (proc == null || proc.thread == null) {
18358                    throw new IllegalArgumentException("Unknown process: " + process);
18359                }
18360
18361                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18362                if (!isDebuggable) {
18363                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18364                        throw new SecurityException("Process not debuggable: " + proc);
18365                    }
18366                }
18367
18368                proc.thread.dumpHeap(managed, path, fd);
18369                fd = null;
18370                return true;
18371            }
18372        } catch (RemoteException e) {
18373            throw new IllegalStateException("Process disappeared");
18374        } finally {
18375            if (fd != null) {
18376                try {
18377                    fd.close();
18378                } catch (IOException e) {
18379                }
18380            }
18381        }
18382    }
18383
18384    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18385    public void monitor() {
18386        synchronized (this) { }
18387    }
18388
18389    void onCoreSettingsChange(Bundle settings) {
18390        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18391            ProcessRecord processRecord = mLruProcesses.get(i);
18392            try {
18393                if (processRecord.thread != null) {
18394                    processRecord.thread.setCoreSettings(settings);
18395                }
18396            } catch (RemoteException re) {
18397                /* ignore */
18398            }
18399        }
18400    }
18401
18402    // Multi-user methods
18403
18404    /**
18405     * Start user, if its not already running, but don't bring it to foreground.
18406     */
18407    @Override
18408    public boolean startUserInBackground(final int userId) {
18409        return startUser(userId, /* foreground */ false);
18410    }
18411
18412    /**
18413     * Start user, if its not already running, and bring it to foreground.
18414     */
18415    boolean startUserInForeground(final int userId, Dialog dlg) {
18416        boolean result = startUser(userId, /* foreground */ true);
18417        dlg.dismiss();
18418        return result;
18419    }
18420
18421    /**
18422     * Refreshes the list of users related to the current user when either a
18423     * user switch happens or when a new related user is started in the
18424     * background.
18425     */
18426    private void updateCurrentProfileIdsLocked() {
18427        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18428                mCurrentUserId, false /* enabledOnly */);
18429        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18430        for (int i = 0; i < currentProfileIds.length; i++) {
18431            currentProfileIds[i] = profiles.get(i).id;
18432        }
18433        mCurrentProfileIds = currentProfileIds;
18434
18435        synchronized (mUserProfileGroupIdsSelfLocked) {
18436            mUserProfileGroupIdsSelfLocked.clear();
18437            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18438            for (int i = 0; i < users.size(); i++) {
18439                UserInfo user = users.get(i);
18440                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18441                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18442                }
18443            }
18444        }
18445    }
18446
18447    private Set getProfileIdsLocked(int userId) {
18448        Set userIds = new HashSet<Integer>();
18449        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18450                userId, false /* enabledOnly */);
18451        for (UserInfo user : profiles) {
18452            userIds.add(Integer.valueOf(user.id));
18453        }
18454        return userIds;
18455    }
18456
18457    @Override
18458    public boolean switchUser(final int userId) {
18459        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18460        String userName;
18461        synchronized (this) {
18462            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18463            if (userInfo == null) {
18464                Slog.w(TAG, "No user info for user #" + userId);
18465                return false;
18466            }
18467            if (userInfo.isManagedProfile()) {
18468                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18469                return false;
18470            }
18471            userName = userInfo.name;
18472            mTargetUserId = userId;
18473        }
18474        mHandler.removeMessages(START_USER_SWITCH_MSG);
18475        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18476        return true;
18477    }
18478
18479    private void showUserSwitchDialog(int userId, String userName) {
18480        // The dialog will show and then initiate the user switch by calling startUserInForeground
18481        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18482                true /* above system */);
18483        d.show();
18484    }
18485
18486    private boolean startUser(final int userId, final boolean foreground) {
18487        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18488                != PackageManager.PERMISSION_GRANTED) {
18489            String msg = "Permission Denial: switchUser() from pid="
18490                    + Binder.getCallingPid()
18491                    + ", uid=" + Binder.getCallingUid()
18492                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18493            Slog.w(TAG, msg);
18494            throw new SecurityException(msg);
18495        }
18496
18497        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18498
18499        final long ident = Binder.clearCallingIdentity();
18500        try {
18501            synchronized (this) {
18502                final int oldUserId = mCurrentUserId;
18503                if (oldUserId == userId) {
18504                    return true;
18505                }
18506
18507                mStackSupervisor.setLockTaskModeLocked(null, false);
18508
18509                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18510                if (userInfo == null) {
18511                    Slog.w(TAG, "No user info for user #" + userId);
18512                    return false;
18513                }
18514                if (foreground && userInfo.isManagedProfile()) {
18515                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18516                    return false;
18517                }
18518
18519                if (foreground) {
18520                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18521                            R.anim.screen_user_enter);
18522                }
18523
18524                boolean needStart = false;
18525
18526                // If the user we are switching to is not currently started, then
18527                // we need to start it now.
18528                if (mStartedUsers.get(userId) == null) {
18529                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18530                    updateStartedUserArrayLocked();
18531                    needStart = true;
18532                }
18533
18534                final Integer userIdInt = Integer.valueOf(userId);
18535                mUserLru.remove(userIdInt);
18536                mUserLru.add(userIdInt);
18537
18538                if (foreground) {
18539                    mCurrentUserId = userId;
18540                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18541                    updateCurrentProfileIdsLocked();
18542                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18543                    // Once the internal notion of the active user has switched, we lock the device
18544                    // with the option to show the user switcher on the keyguard.
18545                    mWindowManager.lockNow(null);
18546                } else {
18547                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18548                    updateCurrentProfileIdsLocked();
18549                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18550                    mUserLru.remove(currentUserIdInt);
18551                    mUserLru.add(currentUserIdInt);
18552                }
18553
18554                final UserStartedState uss = mStartedUsers.get(userId);
18555
18556                // Make sure user is in the started state.  If it is currently
18557                // stopping, we need to knock that off.
18558                if (uss.mState == UserStartedState.STATE_STOPPING) {
18559                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18560                    // so we can just fairly silently bring the user back from
18561                    // the almost-dead.
18562                    uss.mState = UserStartedState.STATE_RUNNING;
18563                    updateStartedUserArrayLocked();
18564                    needStart = true;
18565                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18566                    // This means ACTION_SHUTDOWN has been sent, so we will
18567                    // need to treat this as a new boot of the user.
18568                    uss.mState = UserStartedState.STATE_BOOTING;
18569                    updateStartedUserArrayLocked();
18570                    needStart = true;
18571                }
18572
18573                if (uss.mState == UserStartedState.STATE_BOOTING) {
18574                    // Booting up a new user, need to tell system services about it.
18575                    // Note that this is on the same handler as scheduling of broadcasts,
18576                    // which is important because it needs to go first.
18577                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18578                }
18579
18580                if (foreground) {
18581                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18582                            oldUserId));
18583                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18584                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18585                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18586                            oldUserId, userId, uss));
18587                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18588                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18589                }
18590
18591                if (needStart) {
18592                    // Send USER_STARTED broadcast
18593                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18594                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18595                            | Intent.FLAG_RECEIVER_FOREGROUND);
18596                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18597                    broadcastIntentLocked(null, null, intent,
18598                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18599                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18600                }
18601
18602                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18603                    if (userId != UserHandle.USER_OWNER) {
18604                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18605                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18606                        broadcastIntentLocked(null, null, intent, null,
18607                                new IIntentReceiver.Stub() {
18608                                    public void performReceive(Intent intent, int resultCode,
18609                                            String data, Bundle extras, boolean ordered,
18610                                            boolean sticky, int sendingUser) {
18611                                        onUserInitialized(uss, foreground, oldUserId, userId);
18612                                    }
18613                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18614                                true, false, MY_PID, Process.SYSTEM_UID,
18615                                userId);
18616                        uss.initializing = true;
18617                    } else {
18618                        getUserManagerLocked().makeInitialized(userInfo.id);
18619                    }
18620                }
18621
18622                if (foreground) {
18623                    if (!uss.initializing) {
18624                        moveUserToForeground(uss, oldUserId, userId);
18625                    }
18626                } else {
18627                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18628                }
18629
18630                if (needStart) {
18631                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18632                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18633                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18634                    broadcastIntentLocked(null, null, intent,
18635                            null, new IIntentReceiver.Stub() {
18636                                @Override
18637                                public void performReceive(Intent intent, int resultCode, String data,
18638                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18639                                        throws RemoteException {
18640                                }
18641                            }, 0, null, null,
18642                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18643                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18644                }
18645            }
18646        } finally {
18647            Binder.restoreCallingIdentity(ident);
18648        }
18649
18650        return true;
18651    }
18652
18653    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18654        long ident = Binder.clearCallingIdentity();
18655        try {
18656            Intent intent;
18657            if (oldUserId >= 0) {
18658                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18659                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18660                int count = profiles.size();
18661                for (int i = 0; i < count; i++) {
18662                    int profileUserId = profiles.get(i).id;
18663                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18664                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18665                            | Intent.FLAG_RECEIVER_FOREGROUND);
18666                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18667                    broadcastIntentLocked(null, null, intent,
18668                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18669                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18670                }
18671            }
18672            if (newUserId >= 0) {
18673                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18674                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18675                int count = profiles.size();
18676                for (int i = 0; i < count; i++) {
18677                    int profileUserId = profiles.get(i).id;
18678                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18679                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18680                            | Intent.FLAG_RECEIVER_FOREGROUND);
18681                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18682                    broadcastIntentLocked(null, null, intent,
18683                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18684                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18685                }
18686                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18687                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18688                        | Intent.FLAG_RECEIVER_FOREGROUND);
18689                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18690                broadcastIntentLocked(null, null, intent,
18691                        null, null, 0, null, null,
18692                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18693                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18694            }
18695        } finally {
18696            Binder.restoreCallingIdentity(ident);
18697        }
18698    }
18699
18700    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18701            final int newUserId) {
18702        final int N = mUserSwitchObservers.beginBroadcast();
18703        if (N > 0) {
18704            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18705                int mCount = 0;
18706                @Override
18707                public void sendResult(Bundle data) throws RemoteException {
18708                    synchronized (ActivityManagerService.this) {
18709                        if (mCurUserSwitchCallback == this) {
18710                            mCount++;
18711                            if (mCount == N) {
18712                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18713                            }
18714                        }
18715                    }
18716                }
18717            };
18718            synchronized (this) {
18719                uss.switching = true;
18720                mCurUserSwitchCallback = callback;
18721            }
18722            for (int i=0; i<N; i++) {
18723                try {
18724                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18725                            newUserId, callback);
18726                } catch (RemoteException e) {
18727                }
18728            }
18729        } else {
18730            synchronized (this) {
18731                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18732            }
18733        }
18734        mUserSwitchObservers.finishBroadcast();
18735    }
18736
18737    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18738        synchronized (this) {
18739            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18740            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18741        }
18742    }
18743
18744    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18745        mCurUserSwitchCallback = null;
18746        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18747        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18748                oldUserId, newUserId, uss));
18749    }
18750
18751    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18752        synchronized (this) {
18753            if (foreground) {
18754                moveUserToForeground(uss, oldUserId, newUserId);
18755            }
18756        }
18757
18758        completeSwitchAndInitalize(uss, newUserId, true, false);
18759    }
18760
18761    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18762        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18763        if (homeInFront) {
18764            startHomeActivityLocked(newUserId);
18765        } else {
18766            mStackSupervisor.resumeTopActivitiesLocked();
18767        }
18768        EventLogTags.writeAmSwitchUser(newUserId);
18769        getUserManagerLocked().userForeground(newUserId);
18770        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18771    }
18772
18773    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18774        completeSwitchAndInitalize(uss, newUserId, false, true);
18775    }
18776
18777    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18778            boolean clearInitializing, boolean clearSwitching) {
18779        boolean unfrozen = false;
18780        synchronized (this) {
18781            if (clearInitializing) {
18782                uss.initializing = false;
18783                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18784            }
18785            if (clearSwitching) {
18786                uss.switching = false;
18787            }
18788            if (!uss.switching && !uss.initializing) {
18789                mWindowManager.stopFreezingScreen();
18790                unfrozen = true;
18791            }
18792        }
18793        if (unfrozen) {
18794            final int N = mUserSwitchObservers.beginBroadcast();
18795            for (int i=0; i<N; i++) {
18796                try {
18797                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18798                } catch (RemoteException e) {
18799                }
18800            }
18801            mUserSwitchObservers.finishBroadcast();
18802        }
18803    }
18804
18805    void scheduleStartProfilesLocked() {
18806        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18807            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18808                    DateUtils.SECOND_IN_MILLIS);
18809        }
18810    }
18811
18812    void startProfilesLocked() {
18813        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18814        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18815                mCurrentUserId, false /* enabledOnly */);
18816        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18817        for (UserInfo user : profiles) {
18818            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18819                    && user.id != mCurrentUserId) {
18820                toStart.add(user);
18821            }
18822        }
18823        final int n = toStart.size();
18824        int i = 0;
18825        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18826            startUserInBackground(toStart.get(i).id);
18827        }
18828        if (i < n) {
18829            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18830        }
18831    }
18832
18833    void finishUserBoot(UserStartedState uss) {
18834        synchronized (this) {
18835            if (uss.mState == UserStartedState.STATE_BOOTING
18836                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18837                uss.mState = UserStartedState.STATE_RUNNING;
18838                final int userId = uss.mHandle.getIdentifier();
18839                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18840                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18841                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18842                broadcastIntentLocked(null, null, intent,
18843                        null, null, 0, null, null,
18844                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18845                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18846            }
18847        }
18848    }
18849
18850    void finishUserSwitch(UserStartedState uss) {
18851        synchronized (this) {
18852            finishUserBoot(uss);
18853
18854            startProfilesLocked();
18855
18856            int num = mUserLru.size();
18857            int i = 0;
18858            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18859                Integer oldUserId = mUserLru.get(i);
18860                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18861                if (oldUss == null) {
18862                    // Shouldn't happen, but be sane if it does.
18863                    mUserLru.remove(i);
18864                    num--;
18865                    continue;
18866                }
18867                if (oldUss.mState == UserStartedState.STATE_STOPPING
18868                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18869                    // This user is already stopping, doesn't count.
18870                    num--;
18871                    i++;
18872                    continue;
18873                }
18874                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18875                    // Owner and current can't be stopped, but count as running.
18876                    i++;
18877                    continue;
18878                }
18879                // This is a user to be stopped.
18880                stopUserLocked(oldUserId, null);
18881                num--;
18882                i++;
18883            }
18884        }
18885    }
18886
18887    @Override
18888    public int stopUser(final int userId, final IStopUserCallback callback) {
18889        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18890                != PackageManager.PERMISSION_GRANTED) {
18891            String msg = "Permission Denial: switchUser() from pid="
18892                    + Binder.getCallingPid()
18893                    + ", uid=" + Binder.getCallingUid()
18894                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18895            Slog.w(TAG, msg);
18896            throw new SecurityException(msg);
18897        }
18898        if (userId <= 0) {
18899            throw new IllegalArgumentException("Can't stop primary user " + userId);
18900        }
18901        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18902        synchronized (this) {
18903            return stopUserLocked(userId, callback);
18904        }
18905    }
18906
18907    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18908        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18909        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18910            return ActivityManager.USER_OP_IS_CURRENT;
18911        }
18912
18913        final UserStartedState uss = mStartedUsers.get(userId);
18914        if (uss == null) {
18915            // User is not started, nothing to do...  but we do need to
18916            // callback if requested.
18917            if (callback != null) {
18918                mHandler.post(new Runnable() {
18919                    @Override
18920                    public void run() {
18921                        try {
18922                            callback.userStopped(userId);
18923                        } catch (RemoteException e) {
18924                        }
18925                    }
18926                });
18927            }
18928            return ActivityManager.USER_OP_SUCCESS;
18929        }
18930
18931        if (callback != null) {
18932            uss.mStopCallbacks.add(callback);
18933        }
18934
18935        if (uss.mState != UserStartedState.STATE_STOPPING
18936                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18937            uss.mState = UserStartedState.STATE_STOPPING;
18938            updateStartedUserArrayLocked();
18939
18940            long ident = Binder.clearCallingIdentity();
18941            try {
18942                // We are going to broadcast ACTION_USER_STOPPING and then
18943                // once that is done send a final ACTION_SHUTDOWN and then
18944                // stop the user.
18945                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18946                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18947                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18948                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18949                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18950                // This is the result receiver for the final shutdown broadcast.
18951                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18952                    @Override
18953                    public void performReceive(Intent intent, int resultCode, String data,
18954                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18955                        finishUserStop(uss);
18956                    }
18957                };
18958                // This is the result receiver for the initial stopping broadcast.
18959                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18960                    @Override
18961                    public void performReceive(Intent intent, int resultCode, String data,
18962                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18963                        // On to the next.
18964                        synchronized (ActivityManagerService.this) {
18965                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18966                                // Whoops, we are being started back up.  Abort, abort!
18967                                return;
18968                            }
18969                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18970                        }
18971                        mBatteryStatsService.noteEvent(
18972                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18973                                Integer.toString(userId), userId);
18974                        mSystemServiceManager.stopUser(userId);
18975                        broadcastIntentLocked(null, null, shutdownIntent,
18976                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18977                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18978                    }
18979                };
18980                // Kick things off.
18981                broadcastIntentLocked(null, null, stoppingIntent,
18982                        null, stoppingReceiver, 0, null, null,
18983                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18984                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18985            } finally {
18986                Binder.restoreCallingIdentity(ident);
18987            }
18988        }
18989
18990        return ActivityManager.USER_OP_SUCCESS;
18991    }
18992
18993    void finishUserStop(UserStartedState uss) {
18994        final int userId = uss.mHandle.getIdentifier();
18995        boolean stopped;
18996        ArrayList<IStopUserCallback> callbacks;
18997        synchronized (this) {
18998            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18999            if (mStartedUsers.get(userId) != uss) {
19000                stopped = false;
19001            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19002                stopped = false;
19003            } else {
19004                stopped = true;
19005                // User can no longer run.
19006                mStartedUsers.remove(userId);
19007                mUserLru.remove(Integer.valueOf(userId));
19008                updateStartedUserArrayLocked();
19009
19010                // Clean up all state and processes associated with the user.
19011                // Kill all the processes for the user.
19012                forceStopUserLocked(userId, "finish user");
19013            }
19014
19015            // Explicitly remove the old information in mRecentTasks.
19016            removeRecentTasksForUserLocked(userId);
19017        }
19018
19019        for (int i=0; i<callbacks.size(); i++) {
19020            try {
19021                if (stopped) callbacks.get(i).userStopped(userId);
19022                else callbacks.get(i).userStopAborted(userId);
19023            } catch (RemoteException e) {
19024            }
19025        }
19026
19027        if (stopped) {
19028            mSystemServiceManager.cleanupUser(userId);
19029            synchronized (this) {
19030                mStackSupervisor.removeUserLocked(userId);
19031            }
19032        }
19033    }
19034
19035    @Override
19036    public UserInfo getCurrentUser() {
19037        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19038                != PackageManager.PERMISSION_GRANTED) && (
19039                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19040                != PackageManager.PERMISSION_GRANTED)) {
19041            String msg = "Permission Denial: getCurrentUser() from pid="
19042                    + Binder.getCallingPid()
19043                    + ", uid=" + Binder.getCallingUid()
19044                    + " requires " + INTERACT_ACROSS_USERS;
19045            Slog.w(TAG, msg);
19046            throw new SecurityException(msg);
19047        }
19048        synchronized (this) {
19049            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19050            return getUserManagerLocked().getUserInfo(userId);
19051        }
19052    }
19053
19054    int getCurrentUserIdLocked() {
19055        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19056    }
19057
19058    @Override
19059    public boolean isUserRunning(int userId, boolean orStopped) {
19060        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19061                != PackageManager.PERMISSION_GRANTED) {
19062            String msg = "Permission Denial: isUserRunning() from pid="
19063                    + Binder.getCallingPid()
19064                    + ", uid=" + Binder.getCallingUid()
19065                    + " requires " + INTERACT_ACROSS_USERS;
19066            Slog.w(TAG, msg);
19067            throw new SecurityException(msg);
19068        }
19069        synchronized (this) {
19070            return isUserRunningLocked(userId, orStopped);
19071        }
19072    }
19073
19074    boolean isUserRunningLocked(int userId, boolean orStopped) {
19075        UserStartedState state = mStartedUsers.get(userId);
19076        if (state == null) {
19077            return false;
19078        }
19079        if (orStopped) {
19080            return true;
19081        }
19082        return state.mState != UserStartedState.STATE_STOPPING
19083                && state.mState != UserStartedState.STATE_SHUTDOWN;
19084    }
19085
19086    @Override
19087    public int[] getRunningUserIds() {
19088        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19089                != PackageManager.PERMISSION_GRANTED) {
19090            String msg = "Permission Denial: isUserRunning() from pid="
19091                    + Binder.getCallingPid()
19092                    + ", uid=" + Binder.getCallingUid()
19093                    + " requires " + INTERACT_ACROSS_USERS;
19094            Slog.w(TAG, msg);
19095            throw new SecurityException(msg);
19096        }
19097        synchronized (this) {
19098            return mStartedUserArray;
19099        }
19100    }
19101
19102    private void updateStartedUserArrayLocked() {
19103        int num = 0;
19104        for (int i=0; i<mStartedUsers.size();  i++) {
19105            UserStartedState uss = mStartedUsers.valueAt(i);
19106            // This list does not include stopping users.
19107            if (uss.mState != UserStartedState.STATE_STOPPING
19108                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19109                num++;
19110            }
19111        }
19112        mStartedUserArray = new int[num];
19113        num = 0;
19114        for (int i=0; i<mStartedUsers.size();  i++) {
19115            UserStartedState uss = mStartedUsers.valueAt(i);
19116            if (uss.mState != UserStartedState.STATE_STOPPING
19117                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19118                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19119                num++;
19120            }
19121        }
19122    }
19123
19124    @Override
19125    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19126        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19127                != PackageManager.PERMISSION_GRANTED) {
19128            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19129                    + Binder.getCallingPid()
19130                    + ", uid=" + Binder.getCallingUid()
19131                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19132            Slog.w(TAG, msg);
19133            throw new SecurityException(msg);
19134        }
19135
19136        mUserSwitchObservers.register(observer);
19137    }
19138
19139    @Override
19140    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19141        mUserSwitchObservers.unregister(observer);
19142    }
19143
19144    private boolean userExists(int userId) {
19145        if (userId == 0) {
19146            return true;
19147        }
19148        UserManagerService ums = getUserManagerLocked();
19149        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19150    }
19151
19152    int[] getUsersLocked() {
19153        UserManagerService ums = getUserManagerLocked();
19154        return ums != null ? ums.getUserIds() : new int[] { 0 };
19155    }
19156
19157    UserManagerService getUserManagerLocked() {
19158        if (mUserManager == null) {
19159            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19160            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19161        }
19162        return mUserManager;
19163    }
19164
19165    private int applyUserId(int uid, int userId) {
19166        return UserHandle.getUid(userId, uid);
19167    }
19168
19169    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19170        if (info == null) return null;
19171        ApplicationInfo newInfo = new ApplicationInfo(info);
19172        newInfo.uid = applyUserId(info.uid, userId);
19173        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19174                + info.packageName;
19175        return newInfo;
19176    }
19177
19178    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19179        if (aInfo == null
19180                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19181            return aInfo;
19182        }
19183
19184        ActivityInfo info = new ActivityInfo(aInfo);
19185        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19186        return info;
19187    }
19188
19189    private final class LocalService extends ActivityManagerInternal {
19190        @Override
19191        public void goingToSleep() {
19192            ActivityManagerService.this.goingToSleep();
19193        }
19194
19195        @Override
19196        public void wakingUp() {
19197            ActivityManagerService.this.wakingUp();
19198        }
19199
19200        @Override
19201        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19202                String processName, String abiOverride, int uid, Runnable crashHandler) {
19203            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19204                    processName, abiOverride, uid, crashHandler);
19205        }
19206    }
19207
19208    /**
19209     * An implementation of IAppTask, that allows an app to manage its own tasks via
19210     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19211     * only the process that calls getAppTasks() can call the AppTask methods.
19212     */
19213    class AppTaskImpl extends IAppTask.Stub {
19214        private int mTaskId;
19215        private int mCallingUid;
19216
19217        public AppTaskImpl(int taskId, int callingUid) {
19218            mTaskId = taskId;
19219            mCallingUid = callingUid;
19220        }
19221
19222        private void checkCaller() {
19223            if (mCallingUid != Binder.getCallingUid()) {
19224                throw new SecurityException("Caller " + mCallingUid
19225                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19226            }
19227        }
19228
19229        @Override
19230        public void finishAndRemoveTask() {
19231            checkCaller();
19232
19233            synchronized (ActivityManagerService.this) {
19234                long origId = Binder.clearCallingIdentity();
19235                try {
19236                    if (!removeTaskByIdLocked(mTaskId, false)) {
19237                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19238                    }
19239                } finally {
19240                    Binder.restoreCallingIdentity(origId);
19241                }
19242            }
19243        }
19244
19245        @Override
19246        public ActivityManager.RecentTaskInfo getTaskInfo() {
19247            checkCaller();
19248
19249            synchronized (ActivityManagerService.this) {
19250                long origId = Binder.clearCallingIdentity();
19251                try {
19252                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19253                    if (tr == null) {
19254                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19255                    }
19256                    return createRecentTaskInfoFromTaskRecord(tr);
19257                } finally {
19258                    Binder.restoreCallingIdentity(origId);
19259                }
19260            }
19261        }
19262
19263        @Override
19264        public void moveToFront() {
19265            checkCaller();
19266
19267            final TaskRecord tr;
19268            synchronized (ActivityManagerService.this) {
19269                tr = recentTaskForIdLocked(mTaskId);
19270                if (tr == null) {
19271                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19272                }
19273                if (tr.getRootActivity() != null) {
19274                    moveTaskToFrontLocked(tr.taskId, 0, null);
19275                    return;
19276                }
19277            }
19278
19279            startActivityFromRecentsInner(tr.taskId, null);
19280        }
19281
19282        @Override
19283        public int startActivity(IBinder whoThread, String callingPackage,
19284                Intent intent, String resolvedType, Bundle options) {
19285            checkCaller();
19286
19287            int callingUser = UserHandle.getCallingUserId();
19288            TaskRecord tr;
19289            IApplicationThread appThread;
19290            synchronized (ActivityManagerService.this) {
19291                tr = recentTaskForIdLocked(mTaskId);
19292                if (tr == null) {
19293                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19294                }
19295                appThread = ApplicationThreadNative.asInterface(whoThread);
19296                if (appThread == null) {
19297                    throw new IllegalArgumentException("Bad app thread " + appThread);
19298                }
19299            }
19300            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19301                    resolvedType, null, null, null, null, 0, 0, null, null,
19302                    null, options, callingUser, null, tr);
19303        }
19304
19305        @Override
19306        public void setExcludeFromRecents(boolean exclude) {
19307            checkCaller();
19308
19309            synchronized (ActivityManagerService.this) {
19310                long origId = Binder.clearCallingIdentity();
19311                try {
19312                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19313                    if (tr == null) {
19314                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19315                    }
19316                    Intent intent = tr.getBaseIntent();
19317                    if (exclude) {
19318                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19319                    } else {
19320                        intent.setFlags(intent.getFlags()
19321                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19322                    }
19323                } finally {
19324                    Binder.restoreCallingIdentity(origId);
19325                }
19326            }
19327        }
19328    }
19329}
19330