ActivityManagerService.java revision ff17024e583b170312d82089fd358d278ce16c9a
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.os.BackgroundThread;
65import com.android.internal.os.BatteryStatsImpl;
66import com.android.internal.os.ProcessCpuTracker;
67import com.android.internal.os.TransferPipe;
68import com.android.internal.os.Zygote;
69import com.android.internal.util.FastPrintWriter;
70import com.android.internal.util.FastXmlSerializer;
71import com.android.internal.util.MemInfoReader;
72import com.android.internal.util.Preconditions;
73import com.android.server.AppOpsService;
74import com.android.server.AttributeCache;
75import com.android.server.IntentResolver;
76import com.android.server.LocalServices;
77import com.android.server.ServiceThread;
78import com.android.server.SystemService;
79import com.android.server.SystemServiceManager;
80import com.android.server.Watchdog;
81import com.android.server.am.ActivityStack.ActivityState;
82import com.android.server.firewall.IntentFirewall;
83import com.android.server.pm.Installer;
84import com.android.server.pm.UserManagerService;
85import com.android.server.statusbar.StatusBarManagerInternal;
86import com.android.server.wm.AppTransition;
87import com.android.server.wm.WindowManagerService;
88import com.google.android.collect.Lists;
89import com.google.android.collect.Maps;
90
91import libcore.io.IoUtils;
92
93import org.xmlpull.v1.XmlPullParser;
94import org.xmlpull.v1.XmlPullParserException;
95import org.xmlpull.v1.XmlSerializer;
96
97import android.app.Activity;
98import android.app.ActivityManager;
99import android.app.ActivityManager.RunningTaskInfo;
100import android.app.ActivityManager.StackInfo;
101import android.app.ActivityManagerInternal;
102import android.app.ActivityManagerNative;
103import android.app.ActivityOptions;
104import android.app.ActivityThread;
105import android.app.AlertDialog;
106import android.app.AppGlobals;
107import android.app.ApplicationErrorReport;
108import android.app.Dialog;
109import android.app.IActivityController;
110import android.app.IApplicationThread;
111import android.app.IInstrumentationWatcher;
112import android.app.INotificationManager;
113import android.app.IProcessObserver;
114import android.app.IServiceConnection;
115import android.app.IStopUserCallback;
116import android.app.IUiAutomationConnection;
117import android.app.IUserSwitchObserver;
118import android.app.Instrumentation;
119import android.app.Notification;
120import android.app.NotificationManager;
121import android.app.PendingIntent;
122import android.app.backup.IBackupManager;
123import android.content.ActivityNotFoundException;
124import android.content.BroadcastReceiver;
125import android.content.ClipData;
126import android.content.ComponentCallbacks2;
127import android.content.ComponentName;
128import android.content.ContentProvider;
129import android.content.ContentResolver;
130import android.content.Context;
131import android.content.DialogInterface;
132import android.content.IContentProvider;
133import android.content.IIntentReceiver;
134import android.content.IIntentSender;
135import android.content.Intent;
136import android.content.IntentFilter;
137import android.content.IntentSender;
138import android.content.pm.ActivityInfo;
139import android.content.pm.ApplicationInfo;
140import android.content.pm.ConfigurationInfo;
141import android.content.pm.IPackageDataObserver;
142import android.content.pm.IPackageManager;
143import android.content.pm.InstrumentationInfo;
144import android.content.pm.PackageInfo;
145import android.content.pm.PackageManager;
146import android.content.pm.ParceledListSlice;
147import android.content.pm.UserInfo;
148import android.content.pm.PackageManager.NameNotFoundException;
149import android.content.pm.PathPermission;
150import android.content.pm.ProviderInfo;
151import android.content.pm.ResolveInfo;
152import android.content.pm.ServiceInfo;
153import android.content.res.CompatibilityInfo;
154import android.content.res.Configuration;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.Binder;
159import android.os.Build;
160import android.os.Bundle;
161import android.os.Debug;
162import android.os.DropBoxManager;
163import android.os.Environment;
164import android.os.FactoryTest;
165import android.os.FileObserver;
166import android.os.FileUtils;
167import android.os.Handler;
168import android.os.IBinder;
169import android.os.IPermissionController;
170import android.os.IRemoteCallback;
171import android.os.IUserManager;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.Process;
177import android.os.RemoteCallbackList;
178import android.os.RemoteException;
179import android.os.SELinux;
180import android.os.ServiceManager;
181import android.os.StrictMode;
182import android.os.SystemClock;
183import android.os.SystemProperties;
184import android.os.UpdateLock;
185import android.os.UserHandle;
186import android.os.UserManager;
187import android.provider.Settings;
188import android.text.format.DateUtils;
189import android.text.format.Time;
190import android.util.AtomicFile;
191import android.util.EventLog;
192import android.util.Log;
193import android.util.Pair;
194import android.util.PrintWriterPrinter;
195import android.util.Slog;
196import android.util.SparseArray;
197import android.util.TimeUtils;
198import android.util.Xml;
199import android.view.Gravity;
200import android.view.LayoutInflater;
201import android.view.View;
202import android.view.WindowManager;
203
204import dalvik.system.VMRuntime;
205
206import java.io.BufferedInputStream;
207import java.io.BufferedOutputStream;
208import java.io.DataInputStream;
209import java.io.DataOutputStream;
210import java.io.File;
211import java.io.FileDescriptor;
212import java.io.FileInputStream;
213import java.io.FileNotFoundException;
214import java.io.FileOutputStream;
215import java.io.IOException;
216import java.io.InputStreamReader;
217import java.io.PrintWriter;
218import java.io.StringWriter;
219import java.lang.ref.WeakReference;
220import java.util.ArrayList;
221import java.util.Arrays;
222import java.util.Collections;
223import java.util.Comparator;
224import java.util.HashMap;
225import java.util.HashSet;
226import java.util.Iterator;
227import java.util.List;
228import java.util.Locale;
229import java.util.Map;
230import java.util.Set;
231import java.util.concurrent.atomic.AtomicBoolean;
232import java.util.concurrent.atomic.AtomicLong;
233
234public final class ActivityManagerService extends ActivityManagerNative
235        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
236
237    private static final String USER_DATA_DIR = "/data/user/";
238    // File that stores last updated system version and called preboot receivers
239    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
240
241    static final String TAG = "ActivityManager";
242    static final String TAG_MU = "ActivityManagerServiceMU";
243    static final boolean DEBUG = false;
244    static final boolean localLOGV = DEBUG;
245    static final boolean DEBUG_BACKUP = localLOGV || false;
246    static final boolean DEBUG_BROADCAST = localLOGV || false;
247    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
248    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
249    static final boolean DEBUG_CLEANUP = localLOGV || false;
250    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
251    static final boolean DEBUG_FOCUS = false;
252    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
253    static final boolean DEBUG_MU = localLOGV || false;
254    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
255    static final boolean DEBUG_LRU = localLOGV || false;
256    static final boolean DEBUG_PAUSE = localLOGV || false;
257    static final boolean DEBUG_POWER = localLOGV || false;
258    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
259    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
260    static final boolean DEBUG_PROCESSES = localLOGV || false;
261    static final boolean DEBUG_PROVIDER = localLOGV || false;
262    static final boolean DEBUG_RESULTS = localLOGV || false;
263    static final boolean DEBUG_SERVICE = localLOGV || false;
264    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
265    static final boolean DEBUG_STACK = localLOGV || false;
266    static final boolean DEBUG_SWITCH = localLOGV || false;
267    static final boolean DEBUG_TASKS = localLOGV || false;
268    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
269    static final boolean DEBUG_TRANSITION = localLOGV || false;
270    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
271    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
272    static final boolean DEBUG_VISBILITY = localLOGV || false;
273    static final boolean DEBUG_PSS = localLOGV || false;
274    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
275    static final boolean DEBUG_RECENTS = localLOGV || false;
276    static final boolean VALIDATE_TOKENS = false;
277    static final boolean SHOW_ACTIVITY_START_TIME = true;
278
279    // Control over CPU and battery monitoring.
280    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
281    static final boolean MONITOR_CPU_USAGE = true;
282    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
283    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
284    static final boolean MONITOR_THREAD_CPU_USAGE = false;
285
286    // The flags that are set for all calls we make to the package manager.
287    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
288
289    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
290
291    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
292
293    // Maximum number recent bitmaps to keep in memory.
294    static final int MAX_RECENT_BITMAPS = 5;
295
296    // Amount of time after a call to stopAppSwitches() during which we will
297    // prevent further untrusted switches from happening.
298    static final long APP_SWITCH_DELAY_TIME = 5*1000;
299
300    // How long we wait for a launched process to attach to the activity manager
301    // before we decide it's never going to come up for real.
302    static final int PROC_START_TIMEOUT = 10*1000;
303
304    // How long we wait for a launched process to attach to the activity manager
305    // before we decide it's never going to come up for real, when the process was
306    // started with a wrapper for instrumentation (such as Valgrind) because it
307    // could take much longer than usual.
308    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
309
310    // How long to wait after going idle before forcing apps to GC.
311    static final int GC_TIMEOUT = 5*1000;
312
313    // The minimum amount of time between successive GC requests for a process.
314    static final int GC_MIN_INTERVAL = 60*1000;
315
316    // The minimum amount of time between successive PSS requests for a process.
317    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
318
319    // The minimum amount of time between successive PSS requests for a process
320    // when the request is due to the memory state being lowered.
321    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
322
323    // The rate at which we check for apps using excessive power -- 15 mins.
324    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
325
326    // The minimum sample duration we will allow before deciding we have
327    // enough data on wake locks to start killing things.
328    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
329
330    // The minimum sample duration we will allow before deciding we have
331    // enough data on CPU usage to start killing things.
332    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
333
334    // How long we allow a receiver to run before giving up on it.
335    static final int BROADCAST_FG_TIMEOUT = 10*1000;
336    static final int BROADCAST_BG_TIMEOUT = 60*1000;
337
338    // How long we wait until we timeout on key dispatching.
339    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
340
341    // How long we wait until we timeout on key dispatching during instrumentation.
342    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
343
344    // Amount of time we wait for observers to handle a user switch before
345    // giving up on them and unfreezing the screen.
346    static final int USER_SWITCH_TIMEOUT = 2*1000;
347
348    // Maximum number of users we allow to be running at a time.
349    static final int MAX_RUNNING_USERS = 3;
350
351    // How long to wait in getAssistContextExtras for the activity and foreground services
352    // to respond with the result.
353    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
354
355    // Maximum number of persisted Uri grants a package is allowed
356    static final int MAX_PERSISTED_URI_GRANTS = 128;
357
358    static final int MY_PID = Process.myPid();
359
360    static final String[] EMPTY_STRING_ARRAY = new String[0];
361
362    // How many bytes to write into the dropbox log before truncating
363    static final int DROPBOX_MAX_SIZE = 256 * 1024;
364
365    // Access modes for handleIncomingUser.
366    static final int ALLOW_NON_FULL = 0;
367    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
368    static final int ALLOW_FULL_ONLY = 2;
369
370    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
371
372    /** All system services */
373    SystemServiceManager mSystemServiceManager;
374
375    private Installer mInstaller;
376
377    /** Run all ActivityStacks through this */
378    ActivityStackSupervisor mStackSupervisor;
379
380    public IntentFirewall mIntentFirewall;
381
382    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
383    // default actuion automatically.  Important for devices without direct input
384    // devices.
385    private boolean mShowDialogs = true;
386
387    BroadcastQueue mFgBroadcastQueue;
388    BroadcastQueue mBgBroadcastQueue;
389    // Convenient for easy iteration over the queues. Foreground is first
390    // so that dispatch of foreground broadcasts gets precedence.
391    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
392
393    BroadcastQueue broadcastQueueForIntent(Intent intent) {
394        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
395        if (DEBUG_BACKGROUND_BROADCAST) {
396            Slog.i(TAG, "Broadcast intent " + intent + " on "
397                    + (isFg ? "foreground" : "background")
398                    + " queue");
399        }
400        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
401    }
402
403    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
404        for (BroadcastQueue queue : mBroadcastQueues) {
405            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
406            if (r != null) {
407                return r;
408            }
409        }
410        return null;
411    }
412
413    /**
414     * Activity we have told the window manager to have key focus.
415     */
416    ActivityRecord mFocusedActivity = null;
417
418    /**
419     * List of intents that were used to start the most recent tasks.
420     */
421    ArrayList<TaskRecord> mRecentTasks;
422    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
423
424    /**
425     * For addAppTask: cached of the last activity component that was added.
426     */
427    ComponentName mLastAddedTaskComponent;
428
429    /**
430     * For addAppTask: cached of the last activity uid that was added.
431     */
432    int mLastAddedTaskUid;
433
434    /**
435     * For addAppTask: cached of the last ActivityInfo that was added.
436     */
437    ActivityInfo mLastAddedTaskActivity;
438
439    public class PendingAssistExtras extends Binder implements Runnable {
440        public final ActivityRecord activity;
441        public final Bundle extras;
442        public final Intent intent;
443        public final String hint;
444        public final int userHandle;
445        public boolean haveResult = false;
446        public Bundle result = null;
447        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
448                String _hint, int _userHandle) {
449            activity = _activity;
450            extras = _extras;
451            intent = _intent;
452            hint = _hint;
453            userHandle = _userHandle;
454        }
455        @Override
456        public void run() {
457            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
458            synchronized (this) {
459                haveResult = true;
460                notifyAll();
461            }
462        }
463    }
464
465    final ArrayList<PendingAssistExtras> mPendingAssistExtras
466            = new ArrayList<PendingAssistExtras>();
467
468    /**
469     * Process management.
470     */
471    final ProcessList mProcessList = new ProcessList();
472
473    /**
474     * All of the applications we currently have running organized by name.
475     * The keys are strings of the application package name (as
476     * returned by the package manager), and the keys are ApplicationRecord
477     * objects.
478     */
479    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
480
481    /**
482     * Tracking long-term execution of processes to look for abuse and other
483     * bad app behavior.
484     */
485    final ProcessStatsService mProcessStats;
486
487    /**
488     * The currently running isolated processes.
489     */
490    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
491
492    /**
493     * Counter for assigning isolated process uids, to avoid frequently reusing the
494     * same ones.
495     */
496    int mNextIsolatedProcessUid = 0;
497
498    /**
499     * The currently running heavy-weight process, if any.
500     */
501    ProcessRecord mHeavyWeightProcess = null;
502
503    /**
504     * The last time that various processes have crashed.
505     */
506    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
507
508    /**
509     * Information about a process that is currently marked as bad.
510     */
511    static final class BadProcessInfo {
512        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
513            this.time = time;
514            this.shortMsg = shortMsg;
515            this.longMsg = longMsg;
516            this.stack = stack;
517        }
518
519        final long time;
520        final String shortMsg;
521        final String longMsg;
522        final String stack;
523    }
524
525    /**
526     * Set of applications that we consider to be bad, and will reject
527     * incoming broadcasts from (which the user has no control over).
528     * Processes are added to this set when they have crashed twice within
529     * a minimum amount of time; they are removed from it when they are
530     * later restarted (hopefully due to some user action).  The value is the
531     * time it was added to the list.
532     */
533    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
534
535    /**
536     * All of the processes we currently have running organized by pid.
537     * The keys are the pid running the application.
538     *
539     * <p>NOTE: This object is protected by its own lock, NOT the global
540     * activity manager lock!
541     */
542    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
543
544    /**
545     * All of the processes that have been forced to be foreground.  The key
546     * is the pid of the caller who requested it (we hold a death
547     * link on it).
548     */
549    abstract class ForegroundToken implements IBinder.DeathRecipient {
550        int pid;
551        IBinder token;
552    }
553    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
554
555    /**
556     * List of records for processes that someone had tried to start before the
557     * system was ready.  We don't start them at that point, but ensure they
558     * are started by the time booting is complete.
559     */
560    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
561
562    /**
563     * List of persistent applications that are in the process
564     * of being started.
565     */
566    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
567
568    /**
569     * Processes that are being forcibly torn down.
570     */
571    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
572
573    /**
574     * List of running applications, sorted by recent usage.
575     * The first entry in the list is the least recently used.
576     */
577    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
578
579    /**
580     * Where in mLruProcesses that the processes hosting activities start.
581     */
582    int mLruProcessActivityStart = 0;
583
584    /**
585     * Where in mLruProcesses that the processes hosting services start.
586     * This is after (lower index) than mLruProcessesActivityStart.
587     */
588    int mLruProcessServiceStart = 0;
589
590    /**
591     * List of processes that should gc as soon as things are idle.
592     */
593    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
594
595    /**
596     * Processes we want to collect PSS data from.
597     */
598    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
599
600    /**
601     * Last time we requested PSS data of all processes.
602     */
603    long mLastFullPssTime = SystemClock.uptimeMillis();
604
605    /**
606     * If set, the next time we collect PSS data we should do a full collection
607     * with data from native processes and the kernel.
608     */
609    boolean mFullPssPending = false;
610
611    /**
612     * This is the process holding what we currently consider to be
613     * the "home" activity.
614     */
615    ProcessRecord mHomeProcess;
616
617    /**
618     * This is the process holding the activity the user last visited that
619     * is in a different process from the one they are currently in.
620     */
621    ProcessRecord mPreviousProcess;
622
623    /**
624     * The time at which the previous process was last visible.
625     */
626    long mPreviousProcessVisibleTime;
627
628    /**
629     * Which uses have been started, so are allowed to run code.
630     */
631    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
632
633    /**
634     * LRU list of history of current users.  Most recently current is at the end.
635     */
636    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
637
638    /**
639     * Constant array of the users that are currently started.
640     */
641    int[] mStartedUserArray = new int[] { 0 };
642
643    /**
644     * Registered observers of the user switching mechanics.
645     */
646    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
647            = new RemoteCallbackList<IUserSwitchObserver>();
648
649    /**
650     * Currently active user switch.
651     */
652    Object mCurUserSwitchCallback;
653
654    /**
655     * Packages that the user has asked to have run in screen size
656     * compatibility mode instead of filling the screen.
657     */
658    final CompatModePackages mCompatModePackages;
659
660    /**
661     * Set of IntentSenderRecord objects that are currently active.
662     */
663    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
664            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
665
666    /**
667     * Fingerprints (hashCode()) of stack traces that we've
668     * already logged DropBox entries for.  Guarded by itself.  If
669     * something (rogue user app) forces this over
670     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
671     */
672    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
673    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
674
675    /**
676     * Strict Mode background batched logging state.
677     *
678     * The string buffer is guarded by itself, and its lock is also
679     * used to determine if another batched write is already
680     * in-flight.
681     */
682    private final StringBuilder mStrictModeBuffer = new StringBuilder();
683
684    /**
685     * Keeps track of all IIntentReceivers that have been registered for
686     * broadcasts.  Hash keys are the receiver IBinder, hash value is
687     * a ReceiverList.
688     */
689    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
690            new HashMap<IBinder, ReceiverList>();
691
692    /**
693     * Resolver for broadcast intents to registered receivers.
694     * Holds BroadcastFilter (subclass of IntentFilter).
695     */
696    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
697            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
698        @Override
699        protected boolean allowFilterResult(
700                BroadcastFilter filter, List<BroadcastFilter> dest) {
701            IBinder target = filter.receiverList.receiver.asBinder();
702            for (int i=dest.size()-1; i>=0; i--) {
703                if (dest.get(i).receiverList.receiver.asBinder() == target) {
704                    return false;
705                }
706            }
707            return true;
708        }
709
710        @Override
711        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
712            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
713                    || userId == filter.owningUserId) {
714                return super.newResult(filter, match, userId);
715            }
716            return null;
717        }
718
719        @Override
720        protected BroadcastFilter[] newArray(int size) {
721            return new BroadcastFilter[size];
722        }
723
724        @Override
725        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
726            return packageName.equals(filter.packageName);
727        }
728    };
729
730    /**
731     * State of all active sticky broadcasts per user.  Keys are the action of the
732     * sticky Intent, values are an ArrayList of all broadcasted intents with
733     * that action (which should usually be one).  The SparseArray is keyed
734     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
735     * for stickies that are sent to all users.
736     */
737    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
738            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
739
740    final ActiveServices mServices;
741
742    /**
743     * Backup/restore process management
744     */
745    String mBackupAppName = null;
746    BackupRecord mBackupTarget = null;
747
748    final ProviderMap mProviderMap;
749
750    /**
751     * List of content providers who have clients waiting for them.  The
752     * application is currently being launched and the provider will be
753     * removed from this list once it is published.
754     */
755    final ArrayList<ContentProviderRecord> mLaunchingProviders
756            = new ArrayList<ContentProviderRecord>();
757
758    /**
759     * File storing persisted {@link #mGrantedUriPermissions}.
760     */
761    private final AtomicFile mGrantFile;
762
763    /** XML constants used in {@link #mGrantFile} */
764    private static final String TAG_URI_GRANTS = "uri-grants";
765    private static final String TAG_URI_GRANT = "uri-grant";
766    private static final String ATTR_USER_HANDLE = "userHandle";
767    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
768    private static final String ATTR_TARGET_USER_ID = "targetUserId";
769    private static final String ATTR_SOURCE_PKG = "sourcePkg";
770    private static final String ATTR_TARGET_PKG = "targetPkg";
771    private static final String ATTR_URI = "uri";
772    private static final String ATTR_MODE_FLAGS = "modeFlags";
773    private static final String ATTR_CREATED_TIME = "createdTime";
774    private static final String ATTR_PREFIX = "prefix";
775
776    /**
777     * Global set of specific {@link Uri} permissions that have been granted.
778     * This optimized lookup structure maps from {@link UriPermission#targetUid}
779     * to {@link UriPermission#uri} to {@link UriPermission}.
780     */
781    @GuardedBy("this")
782    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
783            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
784
785    public static class GrantUri {
786        public final int sourceUserId;
787        public final Uri uri;
788        public boolean prefix;
789
790        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
791            this.sourceUserId = sourceUserId;
792            this.uri = uri;
793            this.prefix = prefix;
794        }
795
796        @Override
797        public int hashCode() {
798            return toString().hashCode();
799        }
800
801        @Override
802        public boolean equals(Object o) {
803            if (o instanceof GrantUri) {
804                GrantUri other = (GrantUri) o;
805                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
806                        && prefix == other.prefix;
807            }
808            return false;
809        }
810
811        @Override
812        public String toString() {
813            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
814            if (prefix) result += " [prefix]";
815            return result;
816        }
817
818        public String toSafeString() {
819            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
820            if (prefix) result += " [prefix]";
821            return result;
822        }
823
824        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
825            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
826                    ContentProvider.getUriWithoutUserId(uri), false);
827        }
828    }
829
830    CoreSettingsObserver mCoreSettingsObserver;
831
832    /**
833     * Thread-local storage used to carry caller permissions over through
834     * indirect content-provider access.
835     */
836    private class Identity {
837        public final IBinder token;
838        public final int pid;
839        public final int uid;
840
841        Identity(IBinder _token, int _pid, int _uid) {
842            token = _token;
843            pid = _pid;
844            uid = _uid;
845        }
846    }
847
848    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
849
850    /**
851     * All information we have collected about the runtime performance of
852     * any user id that can impact battery performance.
853     */
854    final BatteryStatsService mBatteryStatsService;
855
856    /**
857     * Information about component usage
858     */
859    UsageStatsManagerInternal mUsageStatsService;
860
861    /**
862     * Information about and control over application operations
863     */
864    final AppOpsService mAppOpsService;
865
866    /**
867     * Save recent tasks information across reboots.
868     */
869    final TaskPersister mTaskPersister;
870
871    /**
872     * Current configuration information.  HistoryRecord objects are given
873     * a reference to this object to indicate which configuration they are
874     * currently running in, so this object must be kept immutable.
875     */
876    Configuration mConfiguration = new Configuration();
877
878    /**
879     * Current sequencing integer of the configuration, for skipping old
880     * configurations.
881     */
882    int mConfigurationSeq = 0;
883
884    /**
885     * Hardware-reported OpenGLES version.
886     */
887    final int GL_ES_VERSION;
888
889    /**
890     * List of initialization arguments to pass to all processes when binding applications to them.
891     * For example, references to the commonly used services.
892     */
893    HashMap<String, IBinder> mAppBindArgs;
894
895    /**
896     * Temporary to avoid allocations.  Protected by main lock.
897     */
898    final StringBuilder mStringBuilder = new StringBuilder(256);
899
900    /**
901     * Used to control how we initialize the service.
902     */
903    ComponentName mTopComponent;
904    String mTopAction = Intent.ACTION_MAIN;
905    String mTopData;
906    boolean mProcessesReady = false;
907    boolean mSystemReady = false;
908    boolean mBooting = false;
909    boolean mCallFinishBooting = false;
910    boolean mBootAnimationComplete = false;
911    boolean mWaitingUpdate = false;
912    boolean mDidUpdate = false;
913    boolean mOnBattery = false;
914    boolean mLaunchWarningShown = false;
915
916    Context mContext;
917
918    int mFactoryTest;
919
920    boolean mCheckedForSetup;
921
922    /**
923     * The time at which we will allow normal application switches again,
924     * after a call to {@link #stopAppSwitches()}.
925     */
926    long mAppSwitchesAllowedTime;
927
928    /**
929     * This is set to true after the first switch after mAppSwitchesAllowedTime
930     * is set; any switches after that will clear the time.
931     */
932    boolean mDidAppSwitch;
933
934    /**
935     * Last time (in realtime) at which we checked for power usage.
936     */
937    long mLastPowerCheckRealtime;
938
939    /**
940     * Last time (in uptime) at which we checked for power usage.
941     */
942    long mLastPowerCheckUptime;
943
944    /**
945     * Set while we are wanting to sleep, to prevent any
946     * activities from being started/resumed.
947     */
948    private boolean mSleeping = false;
949
950    /**
951     * Set while we are running a voice interaction.  This overrides
952     * sleeping while it is active.
953     */
954    private boolean mRunningVoice = false;
955
956    /**
957     * State of external calls telling us if the device is asleep.
958     */
959    private boolean mWentToSleep = false;
960
961    static final int LOCK_SCREEN_HIDDEN = 0;
962    static final int LOCK_SCREEN_LEAVING = 1;
963    static final int LOCK_SCREEN_SHOWN = 2;
964    /**
965     * State of external call telling us if the lock screen is shown.
966     */
967    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
968
969    /**
970     * Set if we are shutting down the system, similar to sleeping.
971     */
972    boolean mShuttingDown = false;
973
974    /**
975     * Current sequence id for oom_adj computation traversal.
976     */
977    int mAdjSeq = 0;
978
979    /**
980     * Current sequence id for process LRU updating.
981     */
982    int mLruSeq = 0;
983
984    /**
985     * Keep track of the non-cached/empty process we last found, to help
986     * determine how to distribute cached/empty processes next time.
987     */
988    int mNumNonCachedProcs = 0;
989
990    /**
991     * Keep track of the number of cached hidden procs, to balance oom adj
992     * distribution between those and empty procs.
993     */
994    int mNumCachedHiddenProcs = 0;
995
996    /**
997     * Keep track of the number of service processes we last found, to
998     * determine on the next iteration which should be B services.
999     */
1000    int mNumServiceProcs = 0;
1001    int mNewNumAServiceProcs = 0;
1002    int mNewNumServiceProcs = 0;
1003
1004    /**
1005     * Allow the current computed overall memory level of the system to go down?
1006     * This is set to false when we are killing processes for reasons other than
1007     * memory management, so that the now smaller process list will not be taken as
1008     * an indication that memory is tighter.
1009     */
1010    boolean mAllowLowerMemLevel = false;
1011
1012    /**
1013     * The last computed memory level, for holding when we are in a state that
1014     * processes are going away for other reasons.
1015     */
1016    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1017
1018    /**
1019     * The last total number of process we have, to determine if changes actually look
1020     * like a shrinking number of process due to lower RAM.
1021     */
1022    int mLastNumProcesses;
1023
1024    /**
1025     * The uptime of the last time we performed idle maintenance.
1026     */
1027    long mLastIdleTime = SystemClock.uptimeMillis();
1028
1029    /**
1030     * Total time spent with RAM that has been added in the past since the last idle time.
1031     */
1032    long mLowRamTimeSinceLastIdle = 0;
1033
1034    /**
1035     * If RAM is currently low, when that horrible situation started.
1036     */
1037    long mLowRamStartTime = 0;
1038
1039    /**
1040     * For reporting to battery stats the current top application.
1041     */
1042    private String mCurResumedPackage = null;
1043    private int mCurResumedUid = -1;
1044
1045    /**
1046     * For reporting to battery stats the apps currently running foreground
1047     * service.  The ProcessMap is package/uid tuples; each of these contain
1048     * an array of the currently foreground processes.
1049     */
1050    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1051            = new ProcessMap<ArrayList<ProcessRecord>>();
1052
1053    /**
1054     * This is set if we had to do a delayed dexopt of an app before launching
1055     * it, to increase the ANR timeouts in that case.
1056     */
1057    boolean mDidDexOpt;
1058
1059    /**
1060     * Set if the systemServer made a call to enterSafeMode.
1061     */
1062    boolean mSafeMode;
1063
1064    String mDebugApp = null;
1065    boolean mWaitForDebugger = false;
1066    boolean mDebugTransient = false;
1067    String mOrigDebugApp = null;
1068    boolean mOrigWaitForDebugger = false;
1069    boolean mAlwaysFinishActivities = false;
1070    IActivityController mController = null;
1071    String mProfileApp = null;
1072    ProcessRecord mProfileProc = null;
1073    String mProfileFile;
1074    ParcelFileDescriptor mProfileFd;
1075    int mSamplingInterval = 0;
1076    boolean mAutoStopProfiler = false;
1077    int mProfileType = 0;
1078    String mOpenGlTraceApp = null;
1079
1080    static class ProcessChangeItem {
1081        static final int CHANGE_ACTIVITIES = 1<<0;
1082        static final int CHANGE_PROCESS_STATE = 1<<1;
1083        int changes;
1084        int uid;
1085        int pid;
1086        int processState;
1087        boolean foregroundActivities;
1088    }
1089
1090    final RemoteCallbackList<IProcessObserver> mProcessObservers
1091            = new RemoteCallbackList<IProcessObserver>();
1092    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1093
1094    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1095            = new ArrayList<ProcessChangeItem>();
1096    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1097            = new ArrayList<ProcessChangeItem>();
1098
1099    /**
1100     * Runtime CPU use collection thread.  This object's lock is used to
1101     * perform synchronization with the thread (notifying it to run).
1102     */
1103    final Thread mProcessCpuThread;
1104
1105    /**
1106     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1107     * Must acquire this object's lock when accessing it.
1108     * NOTE: this lock will be held while doing long operations (trawling
1109     * through all processes in /proc), so it should never be acquired by
1110     * any critical paths such as when holding the main activity manager lock.
1111     */
1112    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1113            MONITOR_THREAD_CPU_USAGE);
1114    final AtomicLong mLastCpuTime = new AtomicLong(0);
1115    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1116
1117    long mLastWriteTime = 0;
1118
1119    /**
1120     * Used to retain an update lock when the foreground activity is in
1121     * immersive mode.
1122     */
1123    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1124
1125    /**
1126     * Set to true after the system has finished booting.
1127     */
1128    boolean mBooted = false;
1129
1130    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1131    int mProcessLimitOverride = -1;
1132
1133    WindowManagerService mWindowManager;
1134
1135    final ActivityThread mSystemThread;
1136
1137    // Holds the current foreground user's id
1138    int mCurrentUserId = 0;
1139    // Holds the target user's id during a user switch
1140    int mTargetUserId = UserHandle.USER_NULL;
1141    // If there are multiple profiles for the current user, their ids are here
1142    // Currently only the primary user can have managed profiles
1143    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1144
1145    /**
1146     * Mapping from each known user ID to the profile group ID it is associated with.
1147     */
1148    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1149
1150    private UserManagerService mUserManager;
1151
1152    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1153        final ProcessRecord mApp;
1154        final int mPid;
1155        final IApplicationThread mAppThread;
1156
1157        AppDeathRecipient(ProcessRecord app, int pid,
1158                IApplicationThread thread) {
1159            if (localLOGV) Slog.v(
1160                TAG, "New death recipient " + this
1161                + " for thread " + thread.asBinder());
1162            mApp = app;
1163            mPid = pid;
1164            mAppThread = thread;
1165        }
1166
1167        @Override
1168        public void binderDied() {
1169            if (localLOGV) Slog.v(
1170                TAG, "Death received in " + this
1171                + " for thread " + mAppThread.asBinder());
1172            synchronized(ActivityManagerService.this) {
1173                appDiedLocked(mApp, mPid, mAppThread);
1174            }
1175        }
1176    }
1177
1178    static final int SHOW_ERROR_MSG = 1;
1179    static final int SHOW_NOT_RESPONDING_MSG = 2;
1180    static final int SHOW_FACTORY_ERROR_MSG = 3;
1181    static final int UPDATE_CONFIGURATION_MSG = 4;
1182    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1183    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1184    static final int SERVICE_TIMEOUT_MSG = 12;
1185    static final int UPDATE_TIME_ZONE = 13;
1186    static final int SHOW_UID_ERROR_MSG = 14;
1187    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1188    static final int PROC_START_TIMEOUT_MSG = 20;
1189    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1190    static final int KILL_APPLICATION_MSG = 22;
1191    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1192    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1193    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1194    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1195    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1196    static final int CLEAR_DNS_CACHE_MSG = 28;
1197    static final int UPDATE_HTTP_PROXY_MSG = 29;
1198    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1199    static final int DISPATCH_PROCESSES_CHANGED = 31;
1200    static final int DISPATCH_PROCESS_DIED = 32;
1201    static final int REPORT_MEM_USAGE_MSG = 33;
1202    static final int REPORT_USER_SWITCH_MSG = 34;
1203    static final int CONTINUE_USER_SWITCH_MSG = 35;
1204    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1205    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1206    static final int PERSIST_URI_GRANTS_MSG = 38;
1207    static final int REQUEST_ALL_PSS_MSG = 39;
1208    static final int START_PROFILES_MSG = 40;
1209    static final int UPDATE_TIME = 41;
1210    static final int SYSTEM_USER_START_MSG = 42;
1211    static final int SYSTEM_USER_CURRENT_MSG = 43;
1212    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1213    static final int FINISH_BOOTING_MSG = 45;
1214    static final int START_USER_SWITCH_MSG = 46;
1215    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1216    static final int DISMISS_DIALOG_MSG = 48;
1217
1218    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1219    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1220    static final int FIRST_COMPAT_MODE_MSG = 300;
1221    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1222
1223    CompatModeDialog mCompatModeDialog;
1224    long mLastMemUsageReportTime = 0;
1225
1226    /**
1227     * Flag whether the current user is a "monkey", i.e. whether
1228     * the UI is driven by a UI automation tool.
1229     */
1230    private boolean mUserIsMonkey;
1231
1232    /** Flag whether the device has a Recents UI */
1233    boolean mHasRecents;
1234
1235    /** The dimensions of the thumbnails in the Recents UI. */
1236    int mThumbnailWidth;
1237    int mThumbnailHeight;
1238
1239    final ServiceThread mHandlerThread;
1240    final MainHandler mHandler;
1241
1242    final class MainHandler extends Handler {
1243        public MainHandler(Looper looper) {
1244            super(looper, null, true);
1245        }
1246
1247        @Override
1248        public void handleMessage(Message msg) {
1249            switch (msg.what) {
1250            case SHOW_ERROR_MSG: {
1251                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1252                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1253                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1254                synchronized (ActivityManagerService.this) {
1255                    ProcessRecord proc = (ProcessRecord)data.get("app");
1256                    AppErrorResult res = (AppErrorResult) data.get("result");
1257                    if (proc != null && proc.crashDialog != null) {
1258                        Slog.e(TAG, "App already has crash dialog: " + proc);
1259                        if (res != null) {
1260                            res.set(0);
1261                        }
1262                        return;
1263                    }
1264                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1265                            >= Process.FIRST_APPLICATION_UID
1266                            && proc.pid != MY_PID);
1267                    for (int userId : mCurrentProfileIds) {
1268                        isBackground &= (proc.userId != userId);
1269                    }
1270                    if (isBackground && !showBackground) {
1271                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1272                        if (res != null) {
1273                            res.set(0);
1274                        }
1275                        return;
1276                    }
1277                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1278                        Dialog d = new AppErrorDialog(mContext,
1279                                ActivityManagerService.this, res, proc);
1280                        d.show();
1281                        proc.crashDialog = d;
1282                    } else {
1283                        // The device is asleep, so just pretend that the user
1284                        // saw a crash dialog and hit "force quit".
1285                        if (res != null) {
1286                            res.set(0);
1287                        }
1288                    }
1289                }
1290
1291                ensureBootCompleted();
1292            } break;
1293            case SHOW_NOT_RESPONDING_MSG: {
1294                synchronized (ActivityManagerService.this) {
1295                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1296                    ProcessRecord proc = (ProcessRecord)data.get("app");
1297                    if (proc != null && proc.anrDialog != null) {
1298                        Slog.e(TAG, "App already has anr dialog: " + proc);
1299                        return;
1300                    }
1301
1302                    Intent intent = new Intent("android.intent.action.ANR");
1303                    if (!mProcessesReady) {
1304                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1305                                | Intent.FLAG_RECEIVER_FOREGROUND);
1306                    }
1307                    broadcastIntentLocked(null, null, intent,
1308                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1309                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1310
1311                    if (mShowDialogs) {
1312                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1313                                mContext, proc, (ActivityRecord)data.get("activity"),
1314                                msg.arg1 != 0);
1315                        d.show();
1316                        proc.anrDialog = d;
1317                    } else {
1318                        // Just kill the app if there is no dialog to be shown.
1319                        killAppAtUsersRequest(proc, null);
1320                    }
1321                }
1322
1323                ensureBootCompleted();
1324            } break;
1325            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1326                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1327                synchronized (ActivityManagerService.this) {
1328                    ProcessRecord proc = (ProcessRecord) data.get("app");
1329                    if (proc == null) {
1330                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1331                        break;
1332                    }
1333                    if (proc.crashDialog != null) {
1334                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1335                        return;
1336                    }
1337                    AppErrorResult res = (AppErrorResult) data.get("result");
1338                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1339                        Dialog d = new StrictModeViolationDialog(mContext,
1340                                ActivityManagerService.this, res, proc);
1341                        d.show();
1342                        proc.crashDialog = d;
1343                    } else {
1344                        // The device is asleep, so just pretend that the user
1345                        // saw a crash dialog and hit "force quit".
1346                        res.set(0);
1347                    }
1348                }
1349                ensureBootCompleted();
1350            } break;
1351            case SHOW_FACTORY_ERROR_MSG: {
1352                Dialog d = new FactoryErrorDialog(
1353                    mContext, msg.getData().getCharSequence("msg"));
1354                d.show();
1355                ensureBootCompleted();
1356            } break;
1357            case UPDATE_CONFIGURATION_MSG: {
1358                final ContentResolver resolver = mContext.getContentResolver();
1359                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1360            } break;
1361            case GC_BACKGROUND_PROCESSES_MSG: {
1362                synchronized (ActivityManagerService.this) {
1363                    performAppGcsIfAppropriateLocked();
1364                }
1365            } break;
1366            case WAIT_FOR_DEBUGGER_MSG: {
1367                synchronized (ActivityManagerService.this) {
1368                    ProcessRecord app = (ProcessRecord)msg.obj;
1369                    if (msg.arg1 != 0) {
1370                        if (!app.waitedForDebugger) {
1371                            Dialog d = new AppWaitingForDebuggerDialog(
1372                                    ActivityManagerService.this,
1373                                    mContext, app);
1374                            app.waitDialog = d;
1375                            app.waitedForDebugger = true;
1376                            d.show();
1377                        }
1378                    } else {
1379                        if (app.waitDialog != null) {
1380                            app.waitDialog.dismiss();
1381                            app.waitDialog = null;
1382                        }
1383                    }
1384                }
1385            } break;
1386            case SERVICE_TIMEOUT_MSG: {
1387                if (mDidDexOpt) {
1388                    mDidDexOpt = false;
1389                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1390                    nmsg.obj = msg.obj;
1391                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1392                    return;
1393                }
1394                mServices.serviceTimeout((ProcessRecord)msg.obj);
1395            } break;
1396            case UPDATE_TIME_ZONE: {
1397                synchronized (ActivityManagerService.this) {
1398                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1399                        ProcessRecord r = mLruProcesses.get(i);
1400                        if (r.thread != null) {
1401                            try {
1402                                r.thread.updateTimeZone();
1403                            } catch (RemoteException ex) {
1404                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1405                            }
1406                        }
1407                    }
1408                }
1409            } break;
1410            case CLEAR_DNS_CACHE_MSG: {
1411                synchronized (ActivityManagerService.this) {
1412                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1413                        ProcessRecord r = mLruProcesses.get(i);
1414                        if (r.thread != null) {
1415                            try {
1416                                r.thread.clearDnsCache();
1417                            } catch (RemoteException ex) {
1418                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1419                            }
1420                        }
1421                    }
1422                }
1423            } break;
1424            case UPDATE_HTTP_PROXY_MSG: {
1425                ProxyInfo proxy = (ProxyInfo)msg.obj;
1426                String host = "";
1427                String port = "";
1428                String exclList = "";
1429                Uri pacFileUrl = Uri.EMPTY;
1430                if (proxy != null) {
1431                    host = proxy.getHost();
1432                    port = Integer.toString(proxy.getPort());
1433                    exclList = proxy.getExclusionListAsString();
1434                    pacFileUrl = proxy.getPacFileUrl();
1435                }
1436                synchronized (ActivityManagerService.this) {
1437                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1438                        ProcessRecord r = mLruProcesses.get(i);
1439                        if (r.thread != null) {
1440                            try {
1441                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1442                            } catch (RemoteException ex) {
1443                                Slog.w(TAG, "Failed to update http proxy for: " +
1444                                        r.info.processName);
1445                            }
1446                        }
1447                    }
1448                }
1449            } break;
1450            case SHOW_UID_ERROR_MSG: {
1451                if (mShowDialogs) {
1452                    AlertDialog d = new BaseErrorDialog(mContext);
1453                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1454                    d.setCancelable(false);
1455                    d.setTitle(mContext.getText(R.string.android_system_label));
1456                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1457                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1458                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1459                    d.show();
1460                }
1461            } break;
1462            case SHOW_FINGERPRINT_ERROR_MSG: {
1463                if (mShowDialogs) {
1464                    AlertDialog d = new BaseErrorDialog(mContext);
1465                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1466                    d.setCancelable(false);
1467                    d.setTitle(mContext.getText(R.string.android_system_label));
1468                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1469                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1470                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1471                    d.show();
1472                }
1473            } break;
1474            case PROC_START_TIMEOUT_MSG: {
1475                if (mDidDexOpt) {
1476                    mDidDexOpt = false;
1477                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1478                    nmsg.obj = msg.obj;
1479                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1480                    return;
1481                }
1482                ProcessRecord app = (ProcessRecord)msg.obj;
1483                synchronized (ActivityManagerService.this) {
1484                    processStartTimedOutLocked(app);
1485                }
1486            } break;
1487            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1488                synchronized (ActivityManagerService.this) {
1489                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1490                }
1491            } break;
1492            case KILL_APPLICATION_MSG: {
1493                synchronized (ActivityManagerService.this) {
1494                    int appid = msg.arg1;
1495                    boolean restart = (msg.arg2 == 1);
1496                    Bundle bundle = (Bundle)msg.obj;
1497                    String pkg = bundle.getString("pkg");
1498                    String reason = bundle.getString("reason");
1499                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1500                            false, UserHandle.USER_ALL, reason);
1501                }
1502            } break;
1503            case FINALIZE_PENDING_INTENT_MSG: {
1504                ((PendingIntentRecord)msg.obj).completeFinalize();
1505            } break;
1506            case POST_HEAVY_NOTIFICATION_MSG: {
1507                INotificationManager inm = NotificationManager.getService();
1508                if (inm == null) {
1509                    return;
1510                }
1511
1512                ActivityRecord root = (ActivityRecord)msg.obj;
1513                ProcessRecord process = root.app;
1514                if (process == null) {
1515                    return;
1516                }
1517
1518                try {
1519                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1520                    String text = mContext.getString(R.string.heavy_weight_notification,
1521                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1522                    Notification notification = new Notification();
1523                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1524                    notification.when = 0;
1525                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1526                    notification.tickerText = text;
1527                    notification.defaults = 0; // please be quiet
1528                    notification.sound = null;
1529                    notification.vibrate = null;
1530                    notification.color = mContext.getResources().getColor(
1531                            com.android.internal.R.color.system_notification_accent_color);
1532                    notification.setLatestEventInfo(context, text,
1533                            mContext.getText(R.string.heavy_weight_notification_detail),
1534                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1535                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1536                                    new UserHandle(root.userId)));
1537
1538                    try {
1539                        int[] outId = new int[1];
1540                        inm.enqueueNotificationWithTag("android", "android", null,
1541                                R.string.heavy_weight_notification,
1542                                notification, outId, root.userId);
1543                    } catch (RuntimeException e) {
1544                        Slog.w(ActivityManagerService.TAG,
1545                                "Error showing notification for heavy-weight app", e);
1546                    } catch (RemoteException e) {
1547                    }
1548                } catch (NameNotFoundException e) {
1549                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1550                }
1551            } break;
1552            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1553                INotificationManager inm = NotificationManager.getService();
1554                if (inm == null) {
1555                    return;
1556                }
1557                try {
1558                    inm.cancelNotificationWithTag("android", null,
1559                            R.string.heavy_weight_notification,  msg.arg1);
1560                } catch (RuntimeException e) {
1561                    Slog.w(ActivityManagerService.TAG,
1562                            "Error canceling notification for service", e);
1563                } catch (RemoteException e) {
1564                }
1565            } break;
1566            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1567                synchronized (ActivityManagerService.this) {
1568                    checkExcessivePowerUsageLocked(true);
1569                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1570                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1571                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1572                }
1573            } break;
1574            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1575                synchronized (ActivityManagerService.this) {
1576                    ActivityRecord ar = (ActivityRecord)msg.obj;
1577                    if (mCompatModeDialog != null) {
1578                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1579                                ar.info.applicationInfo.packageName)) {
1580                            return;
1581                        }
1582                        mCompatModeDialog.dismiss();
1583                        mCompatModeDialog = null;
1584                    }
1585                    if (ar != null && false) {
1586                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1587                                ar.packageName)) {
1588                            int mode = mCompatModePackages.computeCompatModeLocked(
1589                                    ar.info.applicationInfo);
1590                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1591                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1592                                mCompatModeDialog = new CompatModeDialog(
1593                                        ActivityManagerService.this, mContext,
1594                                        ar.info.applicationInfo);
1595                                mCompatModeDialog.show();
1596                            }
1597                        }
1598                    }
1599                }
1600                break;
1601            }
1602            case DISPATCH_PROCESSES_CHANGED: {
1603                dispatchProcessesChanged();
1604                break;
1605            }
1606            case DISPATCH_PROCESS_DIED: {
1607                final int pid = msg.arg1;
1608                final int uid = msg.arg2;
1609                dispatchProcessDied(pid, uid);
1610                break;
1611            }
1612            case REPORT_MEM_USAGE_MSG: {
1613                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1614                Thread thread = new Thread() {
1615                    @Override public void run() {
1616                        reportMemUsage(memInfos);
1617                    }
1618                };
1619                thread.start();
1620                break;
1621            }
1622            case START_USER_SWITCH_MSG: {
1623                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1624                break;
1625            }
1626            case REPORT_USER_SWITCH_MSG: {
1627                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1628                break;
1629            }
1630            case CONTINUE_USER_SWITCH_MSG: {
1631                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1632                break;
1633            }
1634            case USER_SWITCH_TIMEOUT_MSG: {
1635                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1636                break;
1637            }
1638            case IMMERSIVE_MODE_LOCK_MSG: {
1639                final boolean nextState = (msg.arg1 != 0);
1640                if (mUpdateLock.isHeld() != nextState) {
1641                    if (DEBUG_IMMERSIVE) {
1642                        final ActivityRecord r = (ActivityRecord) msg.obj;
1643                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1644                    }
1645                    if (nextState) {
1646                        mUpdateLock.acquire();
1647                    } else {
1648                        mUpdateLock.release();
1649                    }
1650                }
1651                break;
1652            }
1653            case PERSIST_URI_GRANTS_MSG: {
1654                writeGrantedUriPermissions();
1655                break;
1656            }
1657            case REQUEST_ALL_PSS_MSG: {
1658                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1659                break;
1660            }
1661            case START_PROFILES_MSG: {
1662                synchronized (ActivityManagerService.this) {
1663                    startProfilesLocked();
1664                }
1665                break;
1666            }
1667            case UPDATE_TIME: {
1668                synchronized (ActivityManagerService.this) {
1669                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1670                        ProcessRecord r = mLruProcesses.get(i);
1671                        if (r.thread != null) {
1672                            try {
1673                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1674                            } catch (RemoteException ex) {
1675                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1676                            }
1677                        }
1678                    }
1679                }
1680                break;
1681            }
1682            case SYSTEM_USER_START_MSG: {
1683                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1684                        Integer.toString(msg.arg1), msg.arg1);
1685                mSystemServiceManager.startUser(msg.arg1);
1686                break;
1687            }
1688            case SYSTEM_USER_CURRENT_MSG: {
1689                mBatteryStatsService.noteEvent(
1690                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1691                        Integer.toString(msg.arg2), msg.arg2);
1692                mBatteryStatsService.noteEvent(
1693                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1694                        Integer.toString(msg.arg1), msg.arg1);
1695                mSystemServiceManager.switchUser(msg.arg1);
1696                break;
1697            }
1698            case ENTER_ANIMATION_COMPLETE_MSG: {
1699                synchronized (ActivityManagerService.this) {
1700                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1701                    if (r != null && r.app != null && r.app.thread != null) {
1702                        try {
1703                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1704                        } catch (RemoteException e) {
1705                        }
1706                    }
1707                }
1708                break;
1709            }
1710            case FINISH_BOOTING_MSG: {
1711                if (msg.arg1 != 0) {
1712                    finishBooting();
1713                }
1714                if (msg.arg2 != 0) {
1715                    enableScreenAfterBoot();
1716                }
1717                break;
1718            }
1719            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1720                try {
1721                    Locale l = (Locale) msg.obj;
1722                    IBinder service = ServiceManager.getService("mount");
1723                    IMountService mountService = IMountService.Stub.asInterface(service);
1724                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1725                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1726                } catch (RemoteException e) {
1727                    Log.e(TAG, "Error storing locale for decryption UI", e);
1728                }
1729                break;
1730            }
1731            case DISMISS_DIALOG_MSG: {
1732                final Dialog d = (Dialog) msg.obj;
1733                d.dismiss();
1734                break;
1735            }
1736            }
1737        }
1738    };
1739
1740    static final int COLLECT_PSS_BG_MSG = 1;
1741
1742    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1743        @Override
1744        public void handleMessage(Message msg) {
1745            switch (msg.what) {
1746            case COLLECT_PSS_BG_MSG: {
1747                long start = SystemClock.uptimeMillis();
1748                MemInfoReader memInfo = null;
1749                synchronized (ActivityManagerService.this) {
1750                    if (mFullPssPending) {
1751                        mFullPssPending = false;
1752                        memInfo = new MemInfoReader();
1753                    }
1754                }
1755                if (memInfo != null) {
1756                    updateCpuStatsNow();
1757                    long nativeTotalPss = 0;
1758                    synchronized (mProcessCpuTracker) {
1759                        final int N = mProcessCpuTracker.countStats();
1760                        for (int j=0; j<N; j++) {
1761                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1762                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1763                                // This is definitely an application process; skip it.
1764                                continue;
1765                            }
1766                            synchronized (mPidsSelfLocked) {
1767                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1768                                    // This is one of our own processes; skip it.
1769                                    continue;
1770                                }
1771                            }
1772                            nativeTotalPss += Debug.getPss(st.pid, null);
1773                        }
1774                    }
1775                    memInfo.readMemInfo();
1776                    synchronized (ActivityManagerService.this) {
1777                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1778                                + (SystemClock.uptimeMillis()-start) + "ms");
1779                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1780                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1781                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1782                    }
1783                }
1784
1785                int i = 0;
1786                int num = 0;
1787                long[] tmp = new long[1];
1788                do {
1789                    ProcessRecord proc;
1790                    int procState;
1791                    int pid;
1792                    synchronized (ActivityManagerService.this) {
1793                        if (i >= mPendingPssProcesses.size()) {
1794                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1795                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1796                            mPendingPssProcesses.clear();
1797                            return;
1798                        }
1799                        proc = mPendingPssProcesses.get(i);
1800                        procState = proc.pssProcState;
1801                        if (proc.thread != null && procState == proc.setProcState) {
1802                            pid = proc.pid;
1803                        } else {
1804                            proc = null;
1805                            pid = 0;
1806                        }
1807                        i++;
1808                    }
1809                    if (proc != null) {
1810                        long pss = Debug.getPss(pid, tmp);
1811                        synchronized (ActivityManagerService.this) {
1812                            if (proc.thread != null && proc.setProcState == procState
1813                                    && proc.pid == pid) {
1814                                num++;
1815                                proc.lastPssTime = SystemClock.uptimeMillis();
1816                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1817                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1818                                        + ": " + pss + " lastPss=" + proc.lastPss
1819                                        + " state=" + ProcessList.makeProcStateString(procState));
1820                                if (proc.initialIdlePss == 0) {
1821                                    proc.initialIdlePss = pss;
1822                                }
1823                                proc.lastPss = pss;
1824                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1825                                    proc.lastCachedPss = pss;
1826                                }
1827                            }
1828                        }
1829                    }
1830                } while (true);
1831            }
1832            }
1833        }
1834    };
1835
1836    public void setSystemProcess() {
1837        try {
1838            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1839            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1840            ServiceManager.addService("meminfo", new MemBinder(this));
1841            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1842            ServiceManager.addService("dbinfo", new DbBinder(this));
1843            if (MONITOR_CPU_USAGE) {
1844                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1845            }
1846            ServiceManager.addService("permission", new PermissionController(this));
1847
1848            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1849                    "android", STOCK_PM_FLAGS);
1850            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1851
1852            synchronized (this) {
1853                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1854                app.persistent = true;
1855                app.pid = MY_PID;
1856                app.maxAdj = ProcessList.SYSTEM_ADJ;
1857                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1858                mProcessNames.put(app.processName, app.uid, app);
1859                synchronized (mPidsSelfLocked) {
1860                    mPidsSelfLocked.put(app.pid, app);
1861                }
1862                updateLruProcessLocked(app, false, null);
1863                updateOomAdjLocked();
1864            }
1865        } catch (PackageManager.NameNotFoundException e) {
1866            throw new RuntimeException(
1867                    "Unable to find android system package", e);
1868        }
1869    }
1870
1871    public void setWindowManager(WindowManagerService wm) {
1872        mWindowManager = wm;
1873        mStackSupervisor.setWindowManager(wm);
1874    }
1875
1876    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1877        mUsageStatsService = usageStatsManager;
1878    }
1879
1880    public void startObservingNativeCrashes() {
1881        final NativeCrashListener ncl = new NativeCrashListener(this);
1882        ncl.start();
1883    }
1884
1885    public IAppOpsService getAppOpsService() {
1886        return mAppOpsService;
1887    }
1888
1889    static class MemBinder extends Binder {
1890        ActivityManagerService mActivityManagerService;
1891        MemBinder(ActivityManagerService activityManagerService) {
1892            mActivityManagerService = activityManagerService;
1893        }
1894
1895        @Override
1896        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1897            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1898                    != PackageManager.PERMISSION_GRANTED) {
1899                pw.println("Permission Denial: can't dump meminfo from from pid="
1900                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1901                        + " without permission " + android.Manifest.permission.DUMP);
1902                return;
1903            }
1904
1905            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1906        }
1907    }
1908
1909    static class GraphicsBinder extends Binder {
1910        ActivityManagerService mActivityManagerService;
1911        GraphicsBinder(ActivityManagerService activityManagerService) {
1912            mActivityManagerService = activityManagerService;
1913        }
1914
1915        @Override
1916        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1917            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1918                    != PackageManager.PERMISSION_GRANTED) {
1919                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1920                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1921                        + " without permission " + android.Manifest.permission.DUMP);
1922                return;
1923            }
1924
1925            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1926        }
1927    }
1928
1929    static class DbBinder extends Binder {
1930        ActivityManagerService mActivityManagerService;
1931        DbBinder(ActivityManagerService activityManagerService) {
1932            mActivityManagerService = activityManagerService;
1933        }
1934
1935        @Override
1936        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1937            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1938                    != PackageManager.PERMISSION_GRANTED) {
1939                pw.println("Permission Denial: can't dump dbinfo from from pid="
1940                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1941                        + " without permission " + android.Manifest.permission.DUMP);
1942                return;
1943            }
1944
1945            mActivityManagerService.dumpDbInfo(fd, pw, args);
1946        }
1947    }
1948
1949    static class CpuBinder extends Binder {
1950        ActivityManagerService mActivityManagerService;
1951        CpuBinder(ActivityManagerService activityManagerService) {
1952            mActivityManagerService = activityManagerService;
1953        }
1954
1955        @Override
1956        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1957            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1958                    != PackageManager.PERMISSION_GRANTED) {
1959                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1960                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1961                        + " without permission " + android.Manifest.permission.DUMP);
1962                return;
1963            }
1964
1965            synchronized (mActivityManagerService.mProcessCpuTracker) {
1966                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1967                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1968                        SystemClock.uptimeMillis()));
1969            }
1970        }
1971    }
1972
1973    public static final class Lifecycle extends SystemService {
1974        private final ActivityManagerService mService;
1975
1976        public Lifecycle(Context context) {
1977            super(context);
1978            mService = new ActivityManagerService(context);
1979        }
1980
1981        @Override
1982        public void onStart() {
1983            mService.start();
1984        }
1985
1986        public ActivityManagerService getService() {
1987            return mService;
1988        }
1989    }
1990
1991    // Note: This method is invoked on the main thread but may need to attach various
1992    // handlers to other threads.  So take care to be explicit about the looper.
1993    public ActivityManagerService(Context systemContext) {
1994        mContext = systemContext;
1995        mFactoryTest = FactoryTest.getMode();
1996        mSystemThread = ActivityThread.currentActivityThread();
1997
1998        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1999
2000        mHandlerThread = new ServiceThread(TAG,
2001                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2002        mHandlerThread.start();
2003        mHandler = new MainHandler(mHandlerThread.getLooper());
2004
2005        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2006                "foreground", BROADCAST_FG_TIMEOUT, false);
2007        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2008                "background", BROADCAST_BG_TIMEOUT, true);
2009        mBroadcastQueues[0] = mFgBroadcastQueue;
2010        mBroadcastQueues[1] = mBgBroadcastQueue;
2011
2012        mServices = new ActiveServices(this);
2013        mProviderMap = new ProviderMap(this);
2014
2015        // TODO: Move creation of battery stats service outside of activity manager service.
2016        File dataDir = Environment.getDataDirectory();
2017        File systemDir = new File(dataDir, "system");
2018        systemDir.mkdirs();
2019        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2020        mBatteryStatsService.getActiveStatistics().readLocked();
2021        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2022        mOnBattery = DEBUG_POWER ? true
2023                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2024        mBatteryStatsService.getActiveStatistics().setCallback(this);
2025
2026        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2027
2028        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2029
2030        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2031
2032        // User 0 is the first and only user that runs at boot.
2033        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2034        mUserLru.add(Integer.valueOf(0));
2035        updateStartedUserArrayLocked();
2036
2037        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2038            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2039
2040        mConfiguration.setToDefaults();
2041        mConfiguration.setLocale(Locale.getDefault());
2042
2043        mConfigurationSeq = mConfiguration.seq = 1;
2044        mProcessCpuTracker.init();
2045
2046        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2047        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2048        mStackSupervisor = new ActivityStackSupervisor(this);
2049        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2050
2051        mProcessCpuThread = new Thread("CpuTracker") {
2052            @Override
2053            public void run() {
2054                while (true) {
2055                    try {
2056                        try {
2057                            synchronized(this) {
2058                                final long now = SystemClock.uptimeMillis();
2059                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2060                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2061                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2062                                //        + ", write delay=" + nextWriteDelay);
2063                                if (nextWriteDelay < nextCpuDelay) {
2064                                    nextCpuDelay = nextWriteDelay;
2065                                }
2066                                if (nextCpuDelay > 0) {
2067                                    mProcessCpuMutexFree.set(true);
2068                                    this.wait(nextCpuDelay);
2069                                }
2070                            }
2071                        } catch (InterruptedException e) {
2072                        }
2073                        updateCpuStatsNow();
2074                    } catch (Exception e) {
2075                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2076                    }
2077                }
2078            }
2079        };
2080
2081        Watchdog.getInstance().addMonitor(this);
2082        Watchdog.getInstance().addThread(mHandler);
2083    }
2084
2085    public void setSystemServiceManager(SystemServiceManager mgr) {
2086        mSystemServiceManager = mgr;
2087    }
2088
2089    public void setInstaller(Installer installer) {
2090        mInstaller = installer;
2091    }
2092
2093    private void start() {
2094        Process.removeAllProcessGroups();
2095        mProcessCpuThread.start();
2096
2097        mBatteryStatsService.publish(mContext);
2098        mAppOpsService.publish(mContext);
2099        Slog.d("AppOps", "AppOpsService published");
2100        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2101    }
2102
2103    public void initPowerManagement() {
2104        mStackSupervisor.initPowerManagement();
2105        mBatteryStatsService.initPowerManagement();
2106    }
2107
2108    @Override
2109    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2110            throws RemoteException {
2111        if (code == SYSPROPS_TRANSACTION) {
2112            // We need to tell all apps about the system property change.
2113            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2114            synchronized(this) {
2115                final int NP = mProcessNames.getMap().size();
2116                for (int ip=0; ip<NP; ip++) {
2117                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2118                    final int NA = apps.size();
2119                    for (int ia=0; ia<NA; ia++) {
2120                        ProcessRecord app = apps.valueAt(ia);
2121                        if (app.thread != null) {
2122                            procs.add(app.thread.asBinder());
2123                        }
2124                    }
2125                }
2126            }
2127
2128            int N = procs.size();
2129            for (int i=0; i<N; i++) {
2130                Parcel data2 = Parcel.obtain();
2131                try {
2132                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2133                } catch (RemoteException e) {
2134                }
2135                data2.recycle();
2136            }
2137        }
2138        try {
2139            return super.onTransact(code, data, reply, flags);
2140        } catch (RuntimeException e) {
2141            // The activity manager only throws security exceptions, so let's
2142            // log all others.
2143            if (!(e instanceof SecurityException)) {
2144                Slog.wtf(TAG, "Activity Manager Crash", e);
2145            }
2146            throw e;
2147        }
2148    }
2149
2150    void updateCpuStats() {
2151        final long now = SystemClock.uptimeMillis();
2152        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2153            return;
2154        }
2155        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2156            synchronized (mProcessCpuThread) {
2157                mProcessCpuThread.notify();
2158            }
2159        }
2160    }
2161
2162    void updateCpuStatsNow() {
2163        synchronized (mProcessCpuTracker) {
2164            mProcessCpuMutexFree.set(false);
2165            final long now = SystemClock.uptimeMillis();
2166            boolean haveNewCpuStats = false;
2167
2168            if (MONITOR_CPU_USAGE &&
2169                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2170                mLastCpuTime.set(now);
2171                haveNewCpuStats = true;
2172                mProcessCpuTracker.update();
2173                //Slog.i(TAG, mProcessCpu.printCurrentState());
2174                //Slog.i(TAG, "Total CPU usage: "
2175                //        + mProcessCpu.getTotalCpuPercent() + "%");
2176
2177                // Slog the cpu usage if the property is set.
2178                if ("true".equals(SystemProperties.get("events.cpu"))) {
2179                    int user = mProcessCpuTracker.getLastUserTime();
2180                    int system = mProcessCpuTracker.getLastSystemTime();
2181                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2182                    int irq = mProcessCpuTracker.getLastIrqTime();
2183                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2184                    int idle = mProcessCpuTracker.getLastIdleTime();
2185
2186                    int total = user + system + iowait + irq + softIrq + idle;
2187                    if (total == 0) total = 1;
2188
2189                    EventLog.writeEvent(EventLogTags.CPU,
2190                            ((user+system+iowait+irq+softIrq) * 100) / total,
2191                            (user * 100) / total,
2192                            (system * 100) / total,
2193                            (iowait * 100) / total,
2194                            (irq * 100) / total,
2195                            (softIrq * 100) / total);
2196                }
2197            }
2198
2199            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2200            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2201            synchronized(bstats) {
2202                synchronized(mPidsSelfLocked) {
2203                    if (haveNewCpuStats) {
2204                        if (mOnBattery) {
2205                            int perc = bstats.startAddingCpuLocked();
2206                            int totalUTime = 0;
2207                            int totalSTime = 0;
2208                            final int N = mProcessCpuTracker.countStats();
2209                            for (int i=0; i<N; i++) {
2210                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2211                                if (!st.working) {
2212                                    continue;
2213                                }
2214                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2215                                int otherUTime = (st.rel_utime*perc)/100;
2216                                int otherSTime = (st.rel_stime*perc)/100;
2217                                totalUTime += otherUTime;
2218                                totalSTime += otherSTime;
2219                                if (pr != null) {
2220                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2221                                    if (ps == null || !ps.isActive()) {
2222                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2223                                                pr.info.uid, pr.processName);
2224                                    }
2225                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2226                                            st.rel_stime-otherSTime);
2227                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2228                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2229                                } else {
2230                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2231                                    if (ps == null || !ps.isActive()) {
2232                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2233                                                bstats.mapUid(st.uid), st.name);
2234                                    }
2235                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2236                                            st.rel_stime-otherSTime);
2237                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2238                                }
2239                            }
2240                            bstats.finishAddingCpuLocked(perc, totalUTime,
2241                                    totalSTime, cpuSpeedTimes);
2242                        }
2243                    }
2244                }
2245
2246                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2247                    mLastWriteTime = now;
2248                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2249                }
2250            }
2251        }
2252    }
2253
2254    @Override
2255    public void batteryNeedsCpuUpdate() {
2256        updateCpuStatsNow();
2257    }
2258
2259    @Override
2260    public void batteryPowerChanged(boolean onBattery) {
2261        // When plugging in, update the CPU stats first before changing
2262        // the plug state.
2263        updateCpuStatsNow();
2264        synchronized (this) {
2265            synchronized(mPidsSelfLocked) {
2266                mOnBattery = DEBUG_POWER ? true : onBattery;
2267            }
2268        }
2269    }
2270
2271    /**
2272     * Initialize the application bind args. These are passed to each
2273     * process when the bindApplication() IPC is sent to the process. They're
2274     * lazily setup to make sure the services are running when they're asked for.
2275     */
2276    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2277        if (mAppBindArgs == null) {
2278            mAppBindArgs = new HashMap<>();
2279
2280            // Isolated processes won't get this optimization, so that we don't
2281            // violate the rules about which services they have access to.
2282            if (!isolated) {
2283                // Setup the application init args
2284                mAppBindArgs.put("package", ServiceManager.getService("package"));
2285                mAppBindArgs.put("window", ServiceManager.getService("window"));
2286                mAppBindArgs.put(Context.ALARM_SERVICE,
2287                        ServiceManager.getService(Context.ALARM_SERVICE));
2288            }
2289        }
2290        return mAppBindArgs;
2291    }
2292
2293    final void setFocusedActivityLocked(ActivityRecord r) {
2294        if (mFocusedActivity != r) {
2295            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2296            mFocusedActivity = r;
2297            if (r.task != null && r.task.voiceInteractor != null) {
2298                startRunningVoiceLocked();
2299            } else {
2300                finishRunningVoiceLocked();
2301            }
2302            mStackSupervisor.setFocusedStack(r);
2303            if (r != null) {
2304                mWindowManager.setFocusedApp(r.appToken, true);
2305            }
2306            applyUpdateLockStateLocked(r);
2307        }
2308    }
2309
2310    final void clearFocusedActivity(ActivityRecord r) {
2311        if (mFocusedActivity == r) {
2312            mFocusedActivity = null;
2313        }
2314    }
2315
2316    @Override
2317    public void setFocusedStack(int stackId) {
2318        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2319        synchronized (ActivityManagerService.this) {
2320            ActivityStack stack = mStackSupervisor.getStack(stackId);
2321            if (stack != null) {
2322                ActivityRecord r = stack.topRunningActivityLocked(null);
2323                if (r != null) {
2324                    setFocusedActivityLocked(r);
2325                }
2326            }
2327        }
2328    }
2329
2330    @Override
2331    public void notifyActivityDrawn(IBinder token) {
2332        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2333        synchronized (this) {
2334            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2335            if (r != null) {
2336                r.task.stack.notifyActivityDrawnLocked(r);
2337            }
2338        }
2339    }
2340
2341    final void applyUpdateLockStateLocked(ActivityRecord r) {
2342        // Modifications to the UpdateLock state are done on our handler, outside
2343        // the activity manager's locks.  The new state is determined based on the
2344        // state *now* of the relevant activity record.  The object is passed to
2345        // the handler solely for logging detail, not to be consulted/modified.
2346        final boolean nextState = r != null && r.immersive;
2347        mHandler.sendMessage(
2348                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2349    }
2350
2351    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2352        Message msg = Message.obtain();
2353        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2354        msg.obj = r.task.askedCompatMode ? null : r;
2355        mHandler.sendMessage(msg);
2356    }
2357
2358    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2359            String what, Object obj, ProcessRecord srcApp) {
2360        app.lastActivityTime = now;
2361
2362        if (app.activities.size() > 0) {
2363            // Don't want to touch dependent processes that are hosting activities.
2364            return index;
2365        }
2366
2367        int lrui = mLruProcesses.lastIndexOf(app);
2368        if (lrui < 0) {
2369            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2370                    + what + " " + obj + " from " + srcApp);
2371            return index;
2372        }
2373
2374        if (lrui >= index) {
2375            // Don't want to cause this to move dependent processes *back* in the
2376            // list as if they were less frequently used.
2377            return index;
2378        }
2379
2380        if (lrui >= mLruProcessActivityStart) {
2381            // Don't want to touch dependent processes that are hosting activities.
2382            return index;
2383        }
2384
2385        mLruProcesses.remove(lrui);
2386        if (index > 0) {
2387            index--;
2388        }
2389        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2390                + " in LRU list: " + app);
2391        mLruProcesses.add(index, app);
2392        return index;
2393    }
2394
2395    final void removeLruProcessLocked(ProcessRecord app) {
2396        int lrui = mLruProcesses.lastIndexOf(app);
2397        if (lrui >= 0) {
2398            if (!app.killed) {
2399                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2400                Process.killProcessQuiet(app.pid);
2401                Process.killProcessGroup(app.info.uid, app.pid);
2402            }
2403            if (lrui <= mLruProcessActivityStart) {
2404                mLruProcessActivityStart--;
2405            }
2406            if (lrui <= mLruProcessServiceStart) {
2407                mLruProcessServiceStart--;
2408            }
2409            mLruProcesses.remove(lrui);
2410        }
2411    }
2412
2413    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2414            ProcessRecord client) {
2415        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2416                || app.treatLikeActivity;
2417        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2418        if (!activityChange && hasActivity) {
2419            // The process has activities, so we are only allowing activity-based adjustments
2420            // to move it.  It should be kept in the front of the list with other
2421            // processes that have activities, and we don't want those to change their
2422            // order except due to activity operations.
2423            return;
2424        }
2425
2426        mLruSeq++;
2427        final long now = SystemClock.uptimeMillis();
2428        app.lastActivityTime = now;
2429
2430        // First a quick reject: if the app is already at the position we will
2431        // put it, then there is nothing to do.
2432        if (hasActivity) {
2433            final int N = mLruProcesses.size();
2434            if (N > 0 && mLruProcesses.get(N-1) == app) {
2435                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2436                return;
2437            }
2438        } else {
2439            if (mLruProcessServiceStart > 0
2440                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2441                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2442                return;
2443            }
2444        }
2445
2446        int lrui = mLruProcesses.lastIndexOf(app);
2447
2448        if (app.persistent && lrui >= 0) {
2449            // We don't care about the position of persistent processes, as long as
2450            // they are in the list.
2451            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2452            return;
2453        }
2454
2455        /* In progress: compute new position first, so we can avoid doing work
2456           if the process is not actually going to move.  Not yet working.
2457        int addIndex;
2458        int nextIndex;
2459        boolean inActivity = false, inService = false;
2460        if (hasActivity) {
2461            // Process has activities, put it at the very tipsy-top.
2462            addIndex = mLruProcesses.size();
2463            nextIndex = mLruProcessServiceStart;
2464            inActivity = true;
2465        } else if (hasService) {
2466            // Process has services, put it at the top of the service list.
2467            addIndex = mLruProcessActivityStart;
2468            nextIndex = mLruProcessServiceStart;
2469            inActivity = true;
2470            inService = true;
2471        } else  {
2472            // Process not otherwise of interest, it goes to the top of the non-service area.
2473            addIndex = mLruProcessServiceStart;
2474            if (client != null) {
2475                int clientIndex = mLruProcesses.lastIndexOf(client);
2476                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2477                        + app);
2478                if (clientIndex >= 0 && addIndex > clientIndex) {
2479                    addIndex = clientIndex;
2480                }
2481            }
2482            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2483        }
2484
2485        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2486                + mLruProcessActivityStart + "): " + app);
2487        */
2488
2489        if (lrui >= 0) {
2490            if (lrui < mLruProcessActivityStart) {
2491                mLruProcessActivityStart--;
2492            }
2493            if (lrui < mLruProcessServiceStart) {
2494                mLruProcessServiceStart--;
2495            }
2496            /*
2497            if (addIndex > lrui) {
2498                addIndex--;
2499            }
2500            if (nextIndex > lrui) {
2501                nextIndex--;
2502            }
2503            */
2504            mLruProcesses.remove(lrui);
2505        }
2506
2507        /*
2508        mLruProcesses.add(addIndex, app);
2509        if (inActivity) {
2510            mLruProcessActivityStart++;
2511        }
2512        if (inService) {
2513            mLruProcessActivityStart++;
2514        }
2515        */
2516
2517        int nextIndex;
2518        if (hasActivity) {
2519            final int N = mLruProcesses.size();
2520            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2521                // Process doesn't have activities, but has clients with
2522                // activities...  move it up, but one below the top (the top
2523                // should always have a real activity).
2524                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2525                mLruProcesses.add(N-1, app);
2526                // To keep it from spamming the LRU list (by making a bunch of clients),
2527                // we will push down any other entries owned by the app.
2528                final int uid = app.info.uid;
2529                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2530                    ProcessRecord subProc = mLruProcesses.get(i);
2531                    if (subProc.info.uid == uid) {
2532                        // We want to push this one down the list.  If the process after
2533                        // it is for the same uid, however, don't do so, because we don't
2534                        // want them internally to be re-ordered.
2535                        if (mLruProcesses.get(i-1).info.uid != uid) {
2536                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2537                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2538                            ProcessRecord tmp = mLruProcesses.get(i);
2539                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2540                            mLruProcesses.set(i-1, tmp);
2541                            i--;
2542                        }
2543                    } else {
2544                        // A gap, we can stop here.
2545                        break;
2546                    }
2547                }
2548            } else {
2549                // Process has activities, put it at the very tipsy-top.
2550                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2551                mLruProcesses.add(app);
2552            }
2553            nextIndex = mLruProcessServiceStart;
2554        } else if (hasService) {
2555            // Process has services, put it at the top of the service list.
2556            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2557            mLruProcesses.add(mLruProcessActivityStart, app);
2558            nextIndex = mLruProcessServiceStart;
2559            mLruProcessActivityStart++;
2560        } else  {
2561            // Process not otherwise of interest, it goes to the top of the non-service area.
2562            int index = mLruProcessServiceStart;
2563            if (client != null) {
2564                // If there is a client, don't allow the process to be moved up higher
2565                // in the list than that client.
2566                int clientIndex = mLruProcesses.lastIndexOf(client);
2567                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2568                        + " when updating " + app);
2569                if (clientIndex <= lrui) {
2570                    // Don't allow the client index restriction to push it down farther in the
2571                    // list than it already is.
2572                    clientIndex = lrui;
2573                }
2574                if (clientIndex >= 0 && index > clientIndex) {
2575                    index = clientIndex;
2576                }
2577            }
2578            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2579            mLruProcesses.add(index, app);
2580            nextIndex = index-1;
2581            mLruProcessActivityStart++;
2582            mLruProcessServiceStart++;
2583        }
2584
2585        // If the app is currently using a content provider or service,
2586        // bump those processes as well.
2587        for (int j=app.connections.size()-1; j>=0; j--) {
2588            ConnectionRecord cr = app.connections.valueAt(j);
2589            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2590                    && cr.binding.service.app != null
2591                    && cr.binding.service.app.lruSeq != mLruSeq
2592                    && !cr.binding.service.app.persistent) {
2593                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2594                        "service connection", cr, app);
2595            }
2596        }
2597        for (int j=app.conProviders.size()-1; j>=0; j--) {
2598            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2599            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2600                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2601                        "provider reference", cpr, app);
2602            }
2603        }
2604    }
2605
2606    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2607        if (uid == Process.SYSTEM_UID) {
2608            // The system gets to run in any process.  If there are multiple
2609            // processes with the same uid, just pick the first (this
2610            // should never happen).
2611            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2612            if (procs == null) return null;
2613            final int N = procs.size();
2614            for (int i = 0; i < N; i++) {
2615                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2616            }
2617        }
2618        ProcessRecord proc = mProcessNames.get(processName, uid);
2619        if (false && proc != null && !keepIfLarge
2620                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2621                && proc.lastCachedPss >= 4000) {
2622            // Turn this condition on to cause killing to happen regularly, for testing.
2623            if (proc.baseProcessTracker != null) {
2624                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2625            }
2626            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2627        } else if (proc != null && !keepIfLarge
2628                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2629                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2630            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2631            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2632                if (proc.baseProcessTracker != null) {
2633                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2634                }
2635                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2636            }
2637        }
2638        return proc;
2639    }
2640
2641    void ensurePackageDexOpt(String packageName) {
2642        IPackageManager pm = AppGlobals.getPackageManager();
2643        try {
2644            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2645                mDidDexOpt = true;
2646            }
2647        } catch (RemoteException e) {
2648        }
2649    }
2650
2651    boolean isNextTransitionForward() {
2652        int transit = mWindowManager.getPendingAppTransition();
2653        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2654                || transit == AppTransition.TRANSIT_TASK_OPEN
2655                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2656    }
2657
2658    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2659            String processName, String abiOverride, int uid, Runnable crashHandler) {
2660        synchronized(this) {
2661            ApplicationInfo info = new ApplicationInfo();
2662            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2663            // For isolated processes, the former contains the parent's uid and the latter the
2664            // actual uid of the isolated process.
2665            // In the special case introduced by this method (which is, starting an isolated
2666            // process directly from the SystemServer without an actual parent app process) the
2667            // closest thing to a parent's uid is SYSTEM_UID.
2668            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2669            // the |isolated| logic in the ProcessRecord constructor.
2670            info.uid = Process.SYSTEM_UID;
2671            info.processName = processName;
2672            info.className = entryPoint;
2673            info.packageName = "android";
2674            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2675                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2676                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2677                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2678                    crashHandler);
2679            return proc != null ? proc.pid : 0;
2680        }
2681    }
2682
2683    final ProcessRecord startProcessLocked(String processName,
2684            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2685            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2686            boolean isolated, boolean keepIfLarge) {
2687        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2688                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2689                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2690                null /* crashHandler */);
2691    }
2692
2693    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2694            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2695            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2696            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2697        long startTime = SystemClock.elapsedRealtime();
2698        ProcessRecord app;
2699        if (!isolated) {
2700            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2701            checkTime(startTime, "startProcess: after getProcessRecord");
2702        } else {
2703            // If this is an isolated process, it can't re-use an existing process.
2704            app = null;
2705        }
2706        // We don't have to do anything more if:
2707        // (1) There is an existing application record; and
2708        // (2) The caller doesn't think it is dead, OR there is no thread
2709        //     object attached to it so we know it couldn't have crashed; and
2710        // (3) There is a pid assigned to it, so it is either starting or
2711        //     already running.
2712        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2713                + " app=" + app + " knownToBeDead=" + knownToBeDead
2714                + " thread=" + (app != null ? app.thread : null)
2715                + " pid=" + (app != null ? app.pid : -1));
2716        if (app != null && app.pid > 0) {
2717            if (!knownToBeDead || app.thread == null) {
2718                // We already have the app running, or are waiting for it to
2719                // come up (we have a pid but not yet its thread), so keep it.
2720                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2721                // If this is a new package in the process, add the package to the list
2722                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2723                checkTime(startTime, "startProcess: done, added package to proc");
2724                return app;
2725            }
2726
2727            // An application record is attached to a previous process,
2728            // clean it up now.
2729            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2730            checkTime(startTime, "startProcess: bad proc running, killing");
2731            Process.killProcessGroup(app.info.uid, app.pid);
2732            handleAppDiedLocked(app, true, true);
2733            checkTime(startTime, "startProcess: done killing old proc");
2734        }
2735
2736        String hostingNameStr = hostingName != null
2737                ? hostingName.flattenToShortString() : null;
2738
2739        if (!isolated) {
2740            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2741                // If we are in the background, then check to see if this process
2742                // is bad.  If so, we will just silently fail.
2743                if (mBadProcesses.get(info.processName, info.uid) != null) {
2744                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2745                            + "/" + info.processName);
2746                    return null;
2747                }
2748            } else {
2749                // When the user is explicitly starting a process, then clear its
2750                // crash count so that we won't make it bad until they see at
2751                // least one crash dialog again, and make the process good again
2752                // if it had been bad.
2753                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2754                        + "/" + info.processName);
2755                mProcessCrashTimes.remove(info.processName, info.uid);
2756                if (mBadProcesses.get(info.processName, info.uid) != null) {
2757                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2758                            UserHandle.getUserId(info.uid), info.uid,
2759                            info.processName);
2760                    mBadProcesses.remove(info.processName, info.uid);
2761                    if (app != null) {
2762                        app.bad = false;
2763                    }
2764                }
2765            }
2766        }
2767
2768        if (app == null) {
2769            checkTime(startTime, "startProcess: creating new process record");
2770            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2771            app.crashHandler = crashHandler;
2772            if (app == null) {
2773                Slog.w(TAG, "Failed making new process record for "
2774                        + processName + "/" + info.uid + " isolated=" + isolated);
2775                return null;
2776            }
2777            mProcessNames.put(processName, app.uid, app);
2778            if (isolated) {
2779                mIsolatedProcesses.put(app.uid, app);
2780            }
2781            checkTime(startTime, "startProcess: done creating new process record");
2782        } else {
2783            // If this is a new package in the process, add the package to the list
2784            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2785            checkTime(startTime, "startProcess: added package to existing proc");
2786        }
2787
2788        // If the system is not ready yet, then hold off on starting this
2789        // process until it is.
2790        if (!mProcessesReady
2791                && !isAllowedWhileBooting(info)
2792                && !allowWhileBooting) {
2793            if (!mProcessesOnHold.contains(app)) {
2794                mProcessesOnHold.add(app);
2795            }
2796            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2797            checkTime(startTime, "startProcess: returning with proc on hold");
2798            return app;
2799        }
2800
2801        checkTime(startTime, "startProcess: stepping in to startProcess");
2802        startProcessLocked(
2803                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2804        checkTime(startTime, "startProcess: done starting proc!");
2805        return (app.pid != 0) ? app : null;
2806    }
2807
2808    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2809        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2810    }
2811
2812    private final void startProcessLocked(ProcessRecord app,
2813            String hostingType, String hostingNameStr) {
2814        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2815                null /* entryPoint */, null /* entryPointArgs */);
2816    }
2817
2818    private final void startProcessLocked(ProcessRecord app, String hostingType,
2819            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2820        long startTime = SystemClock.elapsedRealtime();
2821        if (app.pid > 0 && app.pid != MY_PID) {
2822            checkTime(startTime, "startProcess: removing from pids map");
2823            synchronized (mPidsSelfLocked) {
2824                mPidsSelfLocked.remove(app.pid);
2825                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2826            }
2827            checkTime(startTime, "startProcess: done removing from pids map");
2828            app.setPid(0);
2829        }
2830
2831        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2832                "startProcessLocked removing on hold: " + app);
2833        mProcessesOnHold.remove(app);
2834
2835        checkTime(startTime, "startProcess: starting to update cpu stats");
2836        updateCpuStats();
2837        checkTime(startTime, "startProcess: done updating cpu stats");
2838
2839        try {
2840            int uid = app.uid;
2841
2842            int[] gids = null;
2843            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2844            if (!app.isolated) {
2845                int[] permGids = null;
2846                try {
2847                    checkTime(startTime, "startProcess: getting gids from package manager");
2848                    final PackageManager pm = mContext.getPackageManager();
2849                    permGids = pm.getPackageGids(app.info.packageName);
2850
2851                    if (Environment.isExternalStorageEmulated()) {
2852                        checkTime(startTime, "startProcess: checking external storage perm");
2853                        if (pm.checkPermission(
2854                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2855                                app.info.packageName) == PERMISSION_GRANTED) {
2856                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2857                        } else {
2858                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2859                        }
2860                    }
2861                } catch (PackageManager.NameNotFoundException e) {
2862                    Slog.w(TAG, "Unable to retrieve gids", e);
2863                }
2864
2865                /*
2866                 * Add shared application and profile GIDs so applications can share some
2867                 * resources like shared libraries and access user-wide resources
2868                 */
2869                if (permGids == null) {
2870                    gids = new int[2];
2871                } else {
2872                    gids = new int[permGids.length + 2];
2873                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2874                }
2875                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2876                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2877            }
2878            checkTime(startTime, "startProcess: building args");
2879            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2880                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2881                        && mTopComponent != null
2882                        && app.processName.equals(mTopComponent.getPackageName())) {
2883                    uid = 0;
2884                }
2885                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2886                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2887                    uid = 0;
2888                }
2889            }
2890            int debugFlags = 0;
2891            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2892                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2893                // Also turn on CheckJNI for debuggable apps. It's quite
2894                // awkward to turn on otherwise.
2895                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2896            }
2897            // Run the app in safe mode if its manifest requests so or the
2898            // system is booted in safe mode.
2899            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2900                mSafeMode == true) {
2901                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2902            }
2903            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2904                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2905            }
2906            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2907                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2908            }
2909            if ("1".equals(SystemProperties.get("debug.assert"))) {
2910                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2911            }
2912
2913            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2914            if (requiredAbi == null) {
2915                requiredAbi = Build.SUPPORTED_ABIS[0];
2916            }
2917
2918            String instructionSet = null;
2919            if (app.info.primaryCpuAbi != null) {
2920                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2921            }
2922
2923            // Start the process.  It will either succeed and return a result containing
2924            // the PID of the new process, or else throw a RuntimeException.
2925            boolean isActivityProcess = (entryPoint == null);
2926            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2927            checkTime(startTime, "startProcess: asking zygote to start proc");
2928            Process.ProcessStartResult startResult = Process.start(entryPoint,
2929                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2930                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
2931                    app.info.dataDir, entryPointArgs);
2932            checkTime(startTime, "startProcess: returned from zygote!");
2933
2934            if (app.isolated) {
2935                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2936            }
2937            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2938            checkTime(startTime, "startProcess: done updating battery stats");
2939
2940            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2941                    UserHandle.getUserId(uid), startResult.pid, uid,
2942                    app.processName, hostingType,
2943                    hostingNameStr != null ? hostingNameStr : "");
2944
2945            if (app.persistent) {
2946                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2947            }
2948
2949            checkTime(startTime, "startProcess: building log message");
2950            StringBuilder buf = mStringBuilder;
2951            buf.setLength(0);
2952            buf.append("Start proc ");
2953            buf.append(app.processName);
2954            if (!isActivityProcess) {
2955                buf.append(" [");
2956                buf.append(entryPoint);
2957                buf.append("]");
2958            }
2959            buf.append(" for ");
2960            buf.append(hostingType);
2961            if (hostingNameStr != null) {
2962                buf.append(" ");
2963                buf.append(hostingNameStr);
2964            }
2965            buf.append(": pid=");
2966            buf.append(startResult.pid);
2967            buf.append(" uid=");
2968            buf.append(uid);
2969            buf.append(" gids={");
2970            if (gids != null) {
2971                for (int gi=0; gi<gids.length; gi++) {
2972                    if (gi != 0) buf.append(", ");
2973                    buf.append(gids[gi]);
2974
2975                }
2976            }
2977            buf.append("}");
2978            if (requiredAbi != null) {
2979                buf.append(" abi=");
2980                buf.append(requiredAbi);
2981            }
2982            Slog.i(TAG, buf.toString());
2983            app.setPid(startResult.pid);
2984            app.usingWrapper = startResult.usingWrapper;
2985            app.removed = false;
2986            app.killed = false;
2987            app.killedByAm = false;
2988            checkTime(startTime, "startProcess: starting to update pids map");
2989            synchronized (mPidsSelfLocked) {
2990                this.mPidsSelfLocked.put(startResult.pid, app);
2991                if (isActivityProcess) {
2992                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2993                    msg.obj = app;
2994                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2995                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2996                }
2997            }
2998            checkTime(startTime, "startProcess: done updating pids map");
2999        } catch (RuntimeException e) {
3000            // XXX do better error recovery.
3001            app.setPid(0);
3002            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3003            if (app.isolated) {
3004                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3005            }
3006            Slog.e(TAG, "Failure starting process " + app.processName, e);
3007        }
3008    }
3009
3010    void updateUsageStats(ActivityRecord component, boolean resumed) {
3011        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3012        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3013        if (resumed) {
3014            if (mUsageStatsService != null) {
3015                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3016                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3017            }
3018            synchronized (stats) {
3019                stats.noteActivityResumedLocked(component.app.uid);
3020            }
3021        } else {
3022            if (mUsageStatsService != null) {
3023                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3024                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3025            }
3026            synchronized (stats) {
3027                stats.noteActivityPausedLocked(component.app.uid);
3028            }
3029        }
3030    }
3031
3032    Intent getHomeIntent() {
3033        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3034        intent.setComponent(mTopComponent);
3035        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3036            intent.addCategory(Intent.CATEGORY_HOME);
3037        }
3038        return intent;
3039    }
3040
3041    boolean startHomeActivityLocked(int userId) {
3042        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3043                && mTopAction == null) {
3044            // We are running in factory test mode, but unable to find
3045            // the factory test app, so just sit around displaying the
3046            // error message and don't try to start anything.
3047            return false;
3048        }
3049        Intent intent = getHomeIntent();
3050        ActivityInfo aInfo =
3051            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3052        if (aInfo != null) {
3053            intent.setComponent(new ComponentName(
3054                    aInfo.applicationInfo.packageName, aInfo.name));
3055            // Don't do this if the home app is currently being
3056            // instrumented.
3057            aInfo = new ActivityInfo(aInfo);
3058            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3059            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3060                    aInfo.applicationInfo.uid, true);
3061            if (app == null || app.instrumentationClass == null) {
3062                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3063                mStackSupervisor.startHomeActivity(intent, aInfo);
3064            }
3065        }
3066
3067        return true;
3068    }
3069
3070    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3071        ActivityInfo ai = null;
3072        ComponentName comp = intent.getComponent();
3073        try {
3074            if (comp != null) {
3075                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3076            } else {
3077                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3078                        intent,
3079                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3080                            flags, userId);
3081
3082                if (info != null) {
3083                    ai = info.activityInfo;
3084                }
3085            }
3086        } catch (RemoteException e) {
3087            // ignore
3088        }
3089
3090        return ai;
3091    }
3092
3093    /**
3094     * Starts the "new version setup screen" if appropriate.
3095     */
3096    void startSetupActivityLocked() {
3097        // Only do this once per boot.
3098        if (mCheckedForSetup) {
3099            return;
3100        }
3101
3102        // We will show this screen if the current one is a different
3103        // version than the last one shown, and we are not running in
3104        // low-level factory test mode.
3105        final ContentResolver resolver = mContext.getContentResolver();
3106        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3107                Settings.Global.getInt(resolver,
3108                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3109            mCheckedForSetup = true;
3110
3111            // See if we should be showing the platform update setup UI.
3112            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3113            List<ResolveInfo> ris = mContext.getPackageManager()
3114                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3115
3116            // We don't allow third party apps to replace this.
3117            ResolveInfo ri = null;
3118            for (int i=0; ris != null && i<ris.size(); i++) {
3119                if ((ris.get(i).activityInfo.applicationInfo.flags
3120                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3121                    ri = ris.get(i);
3122                    break;
3123                }
3124            }
3125
3126            if (ri != null) {
3127                String vers = ri.activityInfo.metaData != null
3128                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3129                        : null;
3130                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3131                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3132                            Intent.METADATA_SETUP_VERSION);
3133                }
3134                String lastVers = Settings.Secure.getString(
3135                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3136                if (vers != null && !vers.equals(lastVers)) {
3137                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3138                    intent.setComponent(new ComponentName(
3139                            ri.activityInfo.packageName, ri.activityInfo.name));
3140                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3141                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3142                            null);
3143                }
3144            }
3145        }
3146    }
3147
3148    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3149        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3150    }
3151
3152    void enforceNotIsolatedCaller(String caller) {
3153        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3154            throw new SecurityException("Isolated process not allowed to call " + caller);
3155        }
3156    }
3157
3158    void enforceShellRestriction(String restriction, int userHandle) {
3159        if (Binder.getCallingUid() == Process.SHELL_UID) {
3160            if (userHandle < 0
3161                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3162                throw new SecurityException("Shell does not have permission to access user "
3163                        + userHandle);
3164            }
3165        }
3166    }
3167
3168    @Override
3169    public int getFrontActivityScreenCompatMode() {
3170        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3171        synchronized (this) {
3172            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3173        }
3174    }
3175
3176    @Override
3177    public void setFrontActivityScreenCompatMode(int mode) {
3178        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3179                "setFrontActivityScreenCompatMode");
3180        synchronized (this) {
3181            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3182        }
3183    }
3184
3185    @Override
3186    public int getPackageScreenCompatMode(String packageName) {
3187        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3188        synchronized (this) {
3189            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3190        }
3191    }
3192
3193    @Override
3194    public void setPackageScreenCompatMode(String packageName, int mode) {
3195        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3196                "setPackageScreenCompatMode");
3197        synchronized (this) {
3198            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3199        }
3200    }
3201
3202    @Override
3203    public boolean getPackageAskScreenCompat(String packageName) {
3204        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3205        synchronized (this) {
3206            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3207        }
3208    }
3209
3210    @Override
3211    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3212        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3213                "setPackageAskScreenCompat");
3214        synchronized (this) {
3215            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3216        }
3217    }
3218
3219    private void dispatchProcessesChanged() {
3220        int N;
3221        synchronized (this) {
3222            N = mPendingProcessChanges.size();
3223            if (mActiveProcessChanges.length < N) {
3224                mActiveProcessChanges = new ProcessChangeItem[N];
3225            }
3226            mPendingProcessChanges.toArray(mActiveProcessChanges);
3227            mAvailProcessChanges.addAll(mPendingProcessChanges);
3228            mPendingProcessChanges.clear();
3229            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3230        }
3231
3232        int i = mProcessObservers.beginBroadcast();
3233        while (i > 0) {
3234            i--;
3235            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3236            if (observer != null) {
3237                try {
3238                    for (int j=0; j<N; j++) {
3239                        ProcessChangeItem item = mActiveProcessChanges[j];
3240                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3241                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3242                                    + item.pid + " uid=" + item.uid + ": "
3243                                    + item.foregroundActivities);
3244                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3245                                    item.foregroundActivities);
3246                        }
3247                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3248                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3249                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3250                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3251                        }
3252                    }
3253                } catch (RemoteException e) {
3254                }
3255            }
3256        }
3257        mProcessObservers.finishBroadcast();
3258    }
3259
3260    private void dispatchProcessDied(int pid, int uid) {
3261        int i = mProcessObservers.beginBroadcast();
3262        while (i > 0) {
3263            i--;
3264            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3265            if (observer != null) {
3266                try {
3267                    observer.onProcessDied(pid, uid);
3268                } catch (RemoteException e) {
3269                }
3270            }
3271        }
3272        mProcessObservers.finishBroadcast();
3273    }
3274
3275    @Override
3276    public final int startActivity(IApplicationThread caller, String callingPackage,
3277            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3278            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3279        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3280            resultWho, requestCode, startFlags, profilerInfo, options,
3281            UserHandle.getCallingUserId());
3282    }
3283
3284    @Override
3285    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3286            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3287            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3288        enforceNotIsolatedCaller("startActivity");
3289        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3290                false, ALLOW_FULL_ONLY, "startActivity", null);
3291        // TODO: Switch to user app stacks here.
3292        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3293                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3294                profilerInfo, null, null, options, userId, null, null);
3295    }
3296
3297    @Override
3298    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3299            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3300            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3301
3302        // This is very dangerous -- it allows you to perform a start activity (including
3303        // permission grants) as any app that may launch one of your own activities.  So
3304        // we will only allow this to be done from activities that are part of the core framework,
3305        // and then only when they are running as the system.
3306        final ActivityRecord sourceRecord;
3307        final int targetUid;
3308        final String targetPackage;
3309        synchronized (this) {
3310            if (resultTo == null) {
3311                throw new SecurityException("Must be called from an activity");
3312            }
3313            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3314            if (sourceRecord == null) {
3315                throw new SecurityException("Called with bad activity token: " + resultTo);
3316            }
3317            if (!sourceRecord.info.packageName.equals("android")) {
3318                throw new SecurityException(
3319                        "Must be called from an activity that is declared in the android package");
3320            }
3321            if (sourceRecord.app == null) {
3322                throw new SecurityException("Called without a process attached to activity");
3323            }
3324            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3325                // This is still okay, as long as this activity is running under the
3326                // uid of the original calling activity.
3327                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3328                    throw new SecurityException(
3329                            "Calling activity in uid " + sourceRecord.app.uid
3330                                    + " must be system uid or original calling uid "
3331                                    + sourceRecord.launchedFromUid);
3332                }
3333            }
3334            targetUid = sourceRecord.launchedFromUid;
3335            targetPackage = sourceRecord.launchedFromPackage;
3336        }
3337
3338        if (userId == UserHandle.USER_NULL) {
3339            userId = UserHandle.getUserId(sourceRecord.app.uid);
3340        }
3341
3342        // TODO: Switch to user app stacks here.
3343        try {
3344            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3345                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3346                    null, null, options, userId, null, null);
3347            return ret;
3348        } catch (SecurityException e) {
3349            // XXX need to figure out how to propagate to original app.
3350            // A SecurityException here is generally actually a fault of the original
3351            // calling activity (such as a fairly granting permissions), so propagate it
3352            // back to them.
3353            /*
3354            StringBuilder msg = new StringBuilder();
3355            msg.append("While launching");
3356            msg.append(intent.toString());
3357            msg.append(": ");
3358            msg.append(e.getMessage());
3359            */
3360            throw e;
3361        }
3362    }
3363
3364    @Override
3365    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3366            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3367            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3368        enforceNotIsolatedCaller("startActivityAndWait");
3369        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3370                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3371        WaitResult res = new WaitResult();
3372        // TODO: Switch to user app stacks here.
3373        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3374                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3375                options, userId, null, null);
3376        return res;
3377    }
3378
3379    @Override
3380    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3381            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3382            int startFlags, Configuration config, Bundle options, int userId) {
3383        enforceNotIsolatedCaller("startActivityWithConfig");
3384        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3385                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3386        // TODO: Switch to user app stacks here.
3387        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3388                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3389                null, null, config, options, userId, null, null);
3390        return ret;
3391    }
3392
3393    @Override
3394    public int startActivityIntentSender(IApplicationThread caller,
3395            IntentSender intent, Intent fillInIntent, String resolvedType,
3396            IBinder resultTo, String resultWho, int requestCode,
3397            int flagsMask, int flagsValues, Bundle options) {
3398        enforceNotIsolatedCaller("startActivityIntentSender");
3399        // Refuse possible leaked file descriptors
3400        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3401            throw new IllegalArgumentException("File descriptors passed in Intent");
3402        }
3403
3404        IIntentSender sender = intent.getTarget();
3405        if (!(sender instanceof PendingIntentRecord)) {
3406            throw new IllegalArgumentException("Bad PendingIntent object");
3407        }
3408
3409        PendingIntentRecord pir = (PendingIntentRecord)sender;
3410
3411        synchronized (this) {
3412            // If this is coming from the currently resumed activity, it is
3413            // effectively saying that app switches are allowed at this point.
3414            final ActivityStack stack = getFocusedStack();
3415            if (stack.mResumedActivity != null &&
3416                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3417                mAppSwitchesAllowedTime = 0;
3418            }
3419        }
3420        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3421                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3422        return ret;
3423    }
3424
3425    @Override
3426    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3427            Intent intent, String resolvedType, IVoiceInteractionSession session,
3428            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3429            Bundle options, int userId) {
3430        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3431                != PackageManager.PERMISSION_GRANTED) {
3432            String msg = "Permission Denial: startVoiceActivity() from pid="
3433                    + Binder.getCallingPid()
3434                    + ", uid=" + Binder.getCallingUid()
3435                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3436            Slog.w(TAG, msg);
3437            throw new SecurityException(msg);
3438        }
3439        if (session == null || interactor == null) {
3440            throw new NullPointerException("null session or interactor");
3441        }
3442        userId = handleIncomingUser(callingPid, callingUid, userId,
3443                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3444        // TODO: Switch to user app stacks here.
3445        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3446                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3447                null, options, userId, null, null);
3448    }
3449
3450    @Override
3451    public boolean startNextMatchingActivity(IBinder callingActivity,
3452            Intent intent, Bundle options) {
3453        // Refuse possible leaked file descriptors
3454        if (intent != null && intent.hasFileDescriptors() == true) {
3455            throw new IllegalArgumentException("File descriptors passed in Intent");
3456        }
3457
3458        synchronized (this) {
3459            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3460            if (r == null) {
3461                ActivityOptions.abort(options);
3462                return false;
3463            }
3464            if (r.app == null || r.app.thread == null) {
3465                // The caller is not running...  d'oh!
3466                ActivityOptions.abort(options);
3467                return false;
3468            }
3469            intent = new Intent(intent);
3470            // The caller is not allowed to change the data.
3471            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3472            // And we are resetting to find the next component...
3473            intent.setComponent(null);
3474
3475            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3476
3477            ActivityInfo aInfo = null;
3478            try {
3479                List<ResolveInfo> resolves =
3480                    AppGlobals.getPackageManager().queryIntentActivities(
3481                            intent, r.resolvedType,
3482                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3483                            UserHandle.getCallingUserId());
3484
3485                // Look for the original activity in the list...
3486                final int N = resolves != null ? resolves.size() : 0;
3487                for (int i=0; i<N; i++) {
3488                    ResolveInfo rInfo = resolves.get(i);
3489                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3490                            && rInfo.activityInfo.name.equals(r.info.name)) {
3491                        // We found the current one...  the next matching is
3492                        // after it.
3493                        i++;
3494                        if (i<N) {
3495                            aInfo = resolves.get(i).activityInfo;
3496                        }
3497                        if (debug) {
3498                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3499                                    + "/" + r.info.name);
3500                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3501                                    + "/" + aInfo.name);
3502                        }
3503                        break;
3504                    }
3505                }
3506            } catch (RemoteException e) {
3507            }
3508
3509            if (aInfo == null) {
3510                // Nobody who is next!
3511                ActivityOptions.abort(options);
3512                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3513                return false;
3514            }
3515
3516            intent.setComponent(new ComponentName(
3517                    aInfo.applicationInfo.packageName, aInfo.name));
3518            intent.setFlags(intent.getFlags()&~(
3519                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3520                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3521                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3522                    Intent.FLAG_ACTIVITY_NEW_TASK));
3523
3524            // Okay now we need to start the new activity, replacing the
3525            // currently running activity.  This is a little tricky because
3526            // we want to start the new one as if the current one is finished,
3527            // but not finish the current one first so that there is no flicker.
3528            // And thus...
3529            final boolean wasFinishing = r.finishing;
3530            r.finishing = true;
3531
3532            // Propagate reply information over to the new activity.
3533            final ActivityRecord resultTo = r.resultTo;
3534            final String resultWho = r.resultWho;
3535            final int requestCode = r.requestCode;
3536            r.resultTo = null;
3537            if (resultTo != null) {
3538                resultTo.removeResultsLocked(r, resultWho, requestCode);
3539            }
3540
3541            final long origId = Binder.clearCallingIdentity();
3542            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3543                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3544                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3545                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3546            Binder.restoreCallingIdentity(origId);
3547
3548            r.finishing = wasFinishing;
3549            if (res != ActivityManager.START_SUCCESS) {
3550                return false;
3551            }
3552            return true;
3553        }
3554    }
3555
3556    @Override
3557    public final int startActivityFromRecents(int taskId, Bundle options) {
3558        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3559            String msg = "Permission Denial: startActivityFromRecents called without " +
3560                    START_TASKS_FROM_RECENTS;
3561            Slog.w(TAG, msg);
3562            throw new SecurityException(msg);
3563        }
3564        return startActivityFromRecentsInner(taskId, options);
3565    }
3566
3567    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3568        final TaskRecord task;
3569        final int callingUid;
3570        final String callingPackage;
3571        final Intent intent;
3572        final int userId;
3573        synchronized (this) {
3574            task = recentTaskForIdLocked(taskId);
3575            if (task == null) {
3576                throw new IllegalArgumentException("Task " + taskId + " not found.");
3577            }
3578            callingUid = task.mCallingUid;
3579            callingPackage = task.mCallingPackage;
3580            intent = task.intent;
3581            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3582            userId = task.userId;
3583        }
3584        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3585                options, userId, null, task);
3586    }
3587
3588    final int startActivityInPackage(int uid, String callingPackage,
3589            Intent intent, String resolvedType, IBinder resultTo,
3590            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3591            IActivityContainer container, TaskRecord inTask) {
3592
3593        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3594                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3595
3596        // TODO: Switch to user app stacks here.
3597        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3598                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3599                null, null, null, options, userId, container, inTask);
3600        return ret;
3601    }
3602
3603    @Override
3604    public final int startActivities(IApplicationThread caller, String callingPackage,
3605            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3606            int userId) {
3607        enforceNotIsolatedCaller("startActivities");
3608        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3609                false, ALLOW_FULL_ONLY, "startActivity", null);
3610        // TODO: Switch to user app stacks here.
3611        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3612                resolvedTypes, resultTo, options, userId);
3613        return ret;
3614    }
3615
3616    final int startActivitiesInPackage(int uid, String callingPackage,
3617            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3618            Bundle options, int userId) {
3619
3620        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3621                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3622        // TODO: Switch to user app stacks here.
3623        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3624                resultTo, options, userId);
3625        return ret;
3626    }
3627
3628    //explicitly remove thd old information in mRecentTasks when removing existing user.
3629    private void removeRecentTasksForUserLocked(int userId) {
3630        if(userId <= 0) {
3631            Slog.i(TAG, "Can't remove recent task on user " + userId);
3632            return;
3633        }
3634
3635        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3636            TaskRecord tr = mRecentTasks.get(i);
3637            if (tr.userId == userId) {
3638                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3639                        + " when finishing user" + userId);
3640                mRecentTasks.remove(i);
3641                tr.removedFromRecents(mTaskPersister);
3642            }
3643        }
3644
3645        // Remove tasks from persistent storage.
3646        mTaskPersister.wakeup(null, true);
3647    }
3648
3649    // Sort by taskId
3650    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3651        @Override
3652        public int compare(TaskRecord lhs, TaskRecord rhs) {
3653            return rhs.taskId - lhs.taskId;
3654        }
3655    };
3656
3657    // Extract the affiliates of the chain containing mRecentTasks[start].
3658    private int processNextAffiliateChain(int start) {
3659        final TaskRecord startTask = mRecentTasks.get(start);
3660        final int affiliateId = startTask.mAffiliatedTaskId;
3661
3662        // Quick identification of isolated tasks. I.e. those not launched behind.
3663        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3664                startTask.mNextAffiliate == null) {
3665            // There is still a slim chance that there are other tasks that point to this task
3666            // and that the chain is so messed up that this task no longer points to them but
3667            // the gain of this optimization outweighs the risk.
3668            startTask.inRecents = true;
3669            return start + 1;
3670        }
3671
3672        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3673        mTmpRecents.clear();
3674        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3675            final TaskRecord task = mRecentTasks.get(i);
3676            if (task.mAffiliatedTaskId == affiliateId) {
3677                mRecentTasks.remove(i);
3678                mTmpRecents.add(task);
3679            }
3680        }
3681
3682        // Sort them all by taskId. That is the order they were create in and that order will
3683        // always be correct.
3684        Collections.sort(mTmpRecents, mTaskRecordComparator);
3685
3686        // Go through and fix up the linked list.
3687        // The first one is the end of the chain and has no next.
3688        final TaskRecord first = mTmpRecents.get(0);
3689        first.inRecents = true;
3690        if (first.mNextAffiliate != null) {
3691            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3692            first.setNextAffiliate(null);
3693            mTaskPersister.wakeup(first, false);
3694        }
3695        // Everything in the middle is doubly linked from next to prev.
3696        final int tmpSize = mTmpRecents.size();
3697        for (int i = 0; i < tmpSize - 1; ++i) {
3698            final TaskRecord next = mTmpRecents.get(i);
3699            final TaskRecord prev = mTmpRecents.get(i + 1);
3700            if (next.mPrevAffiliate != prev) {
3701                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3702                        " setting prev=" + prev);
3703                next.setPrevAffiliate(prev);
3704                mTaskPersister.wakeup(next, false);
3705            }
3706            if (prev.mNextAffiliate != next) {
3707                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3708                        " setting next=" + next);
3709                prev.setNextAffiliate(next);
3710                mTaskPersister.wakeup(prev, false);
3711            }
3712            prev.inRecents = true;
3713        }
3714        // The last one is the beginning of the list and has no prev.
3715        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3716        if (last.mPrevAffiliate != null) {
3717            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3718            last.setPrevAffiliate(null);
3719            mTaskPersister.wakeup(last, false);
3720        }
3721
3722        // Insert the group back into mRecentTasks at start.
3723        mRecentTasks.addAll(start, mTmpRecents);
3724
3725        // Let the caller know where we left off.
3726        return start + tmpSize;
3727    }
3728
3729    /**
3730     * Update the recent tasks lists: make sure tasks should still be here (their
3731     * applications / activities still exist), update their availability, fixup ordering
3732     * of affiliations.
3733     */
3734    void cleanupRecentTasksLocked(int userId) {
3735        if (mRecentTasks == null) {
3736            // Happens when called from the packagemanager broadcast before boot.
3737            return;
3738        }
3739
3740        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3741        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3742        final IPackageManager pm = AppGlobals.getPackageManager();
3743        final ActivityInfo dummyAct = new ActivityInfo();
3744        final ApplicationInfo dummyApp = new ApplicationInfo();
3745
3746        int N = mRecentTasks.size();
3747
3748        int[] users = userId == UserHandle.USER_ALL
3749                ? getUsersLocked() : new int[] { userId };
3750        for (int user : users) {
3751            for (int i = 0; i < N; i++) {
3752                TaskRecord task = mRecentTasks.get(i);
3753                if (task.userId != user) {
3754                    // Only look at tasks for the user ID of interest.
3755                    continue;
3756                }
3757                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3758                    // This situation is broken, and we should just get rid of it now.
3759                    mRecentTasks.remove(i);
3760                    task.removedFromRecents(mTaskPersister);
3761                    i--;
3762                    N--;
3763                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3764                    continue;
3765                }
3766                // Check whether this activity is currently available.
3767                if (task.realActivity != null) {
3768                    ActivityInfo ai = availActCache.get(task.realActivity);
3769                    if (ai == null) {
3770                        try {
3771                            ai = pm.getActivityInfo(task.realActivity,
3772                                    PackageManager.GET_UNINSTALLED_PACKAGES
3773                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3774                        } catch (RemoteException e) {
3775                            // Will never happen.
3776                            continue;
3777                        }
3778                        if (ai == null) {
3779                            ai = dummyAct;
3780                        }
3781                        availActCache.put(task.realActivity, ai);
3782                    }
3783                    if (ai == dummyAct) {
3784                        // This could be either because the activity no longer exists, or the
3785                        // app is temporarily gone.  For the former we want to remove the recents
3786                        // entry; for the latter we want to mark it as unavailable.
3787                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3788                        if (app == null) {
3789                            try {
3790                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3791                                        PackageManager.GET_UNINSTALLED_PACKAGES
3792                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3793                            } catch (RemoteException e) {
3794                                // Will never happen.
3795                                continue;
3796                            }
3797                            if (app == null) {
3798                                app = dummyApp;
3799                            }
3800                            availAppCache.put(task.realActivity.getPackageName(), app);
3801                        }
3802                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3803                            // Doesn't exist any more!  Good-bye.
3804                            mRecentTasks.remove(i);
3805                            task.removedFromRecents(mTaskPersister);
3806                            i--;
3807                            N--;
3808                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3809                            continue;
3810                        } else {
3811                            // Otherwise just not available for now.
3812                            if (task.isAvailable) {
3813                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3814                                        + task);
3815                            }
3816                            task.isAvailable = false;
3817                        }
3818                    } else {
3819                        if (!ai.enabled || !ai.applicationInfo.enabled
3820                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3821                            if (task.isAvailable) {
3822                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3823                                        + task + " (enabled=" + ai.enabled + "/"
3824                                        + ai.applicationInfo.enabled +  " flags="
3825                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3826                            }
3827                            task.isAvailable = false;
3828                        } else {
3829                            if (!task.isAvailable) {
3830                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3831                                        + task);
3832                            }
3833                            task.isAvailable = true;
3834                        }
3835                    }
3836                }
3837            }
3838        }
3839
3840        // Verify the affiliate chain for each task.
3841        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
3842        }
3843
3844        mTmpRecents.clear();
3845        // mRecentTasks is now in sorted, affiliated order.
3846    }
3847
3848    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3849        int N = mRecentTasks.size();
3850        TaskRecord top = task;
3851        int topIndex = taskIndex;
3852        while (top.mNextAffiliate != null && topIndex > 0) {
3853            top = top.mNextAffiliate;
3854            topIndex--;
3855        }
3856        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3857                + topIndex + " from intial " + taskIndex);
3858        // Find the end of the chain, doing a sanity check along the way.
3859        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3860        int endIndex = topIndex;
3861        TaskRecord prev = top;
3862        while (endIndex < N) {
3863            TaskRecord cur = mRecentTasks.get(endIndex);
3864            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3865                    + endIndex + " " + cur);
3866            if (cur == top) {
3867                // Verify start of the chain.
3868                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3869                    Slog.wtf(TAG, "Bad chain @" + endIndex
3870                            + ": first task has next affiliate: " + prev);
3871                    sane = false;
3872                    break;
3873                }
3874            } else {
3875                // Verify middle of the chain's next points back to the one before.
3876                if (cur.mNextAffiliate != prev
3877                        || cur.mNextAffiliateTaskId != prev.taskId) {
3878                    Slog.wtf(TAG, "Bad chain @" + endIndex
3879                            + ": middle task " + cur + " @" + endIndex
3880                            + " has bad next affiliate "
3881                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3882                            + ", expected " + prev);
3883                    sane = false;
3884                    break;
3885                }
3886            }
3887            if (cur.mPrevAffiliateTaskId == -1) {
3888                // Chain ends here.
3889                if (cur.mPrevAffiliate != null) {
3890                    Slog.wtf(TAG, "Bad chain @" + endIndex
3891                            + ": last task " + cur + " has previous affiliate "
3892                            + cur.mPrevAffiliate);
3893                    sane = false;
3894                }
3895                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3896                break;
3897            } else {
3898                // Verify middle of the chain's prev points to a valid item.
3899                if (cur.mPrevAffiliate == null) {
3900                    Slog.wtf(TAG, "Bad chain @" + endIndex
3901                            + ": task " + cur + " has previous affiliate "
3902                            + cur.mPrevAffiliate + " but should be id "
3903                            + cur.mPrevAffiliate);
3904                    sane = false;
3905                    break;
3906                }
3907            }
3908            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3909                Slog.wtf(TAG, "Bad chain @" + endIndex
3910                        + ": task " + cur + " has affiliated id "
3911                        + cur.mAffiliatedTaskId + " but should be "
3912                        + task.mAffiliatedTaskId);
3913                sane = false;
3914                break;
3915            }
3916            prev = cur;
3917            endIndex++;
3918            if (endIndex >= N) {
3919                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3920                        + ": last task " + prev);
3921                sane = false;
3922                break;
3923            }
3924        }
3925        if (sane) {
3926            if (endIndex < taskIndex) {
3927                Slog.wtf(TAG, "Bad chain @" + endIndex
3928                        + ": did not extend to task " + task + " @" + taskIndex);
3929                sane = false;
3930            }
3931        }
3932        if (sane) {
3933            // All looks good, we can just move all of the affiliated tasks
3934            // to the top.
3935            for (int i=topIndex; i<=endIndex; i++) {
3936                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
3937                        + " from " + i + " to " + (i-topIndex));
3938                TaskRecord cur = mRecentTasks.remove(i);
3939                mRecentTasks.add(i-topIndex, cur);
3940            }
3941            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
3942                    + " to " + endIndex);
3943            return true;
3944        }
3945
3946        // Whoops, couldn't do it.
3947        return false;
3948    }
3949
3950    final void addRecentTaskLocked(TaskRecord task) {
3951        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
3952                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
3953
3954        int N = mRecentTasks.size();
3955        // Quick case: check if the top-most recent task is the same.
3956        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
3957            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
3958            return;
3959        }
3960        // Another quick case: check if this is part of a set of affiliated
3961        // tasks that are at the top.
3962        if (isAffiliated && N > 0 && task.inRecents
3963                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
3964            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
3965                    + " at top when adding " + task);
3966            return;
3967        }
3968        // Another quick case: never add voice sessions.
3969        if (task.voiceSession != null) {
3970            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
3971            return;
3972        }
3973
3974        boolean needAffiliationFix = false;
3975
3976        // Slightly less quick case: the task is already in recents, so all we need
3977        // to do is move it.
3978        if (task.inRecents) {
3979            int taskIndex = mRecentTasks.indexOf(task);
3980            if (taskIndex >= 0) {
3981                if (!isAffiliated) {
3982                    // Simple case: this is not an affiliated task, so we just move it to the front.
3983                    mRecentTasks.remove(taskIndex);
3984                    mRecentTasks.add(0, task);
3985                    notifyTaskPersisterLocked(task, false);
3986                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
3987                            + " from " + taskIndex);
3988                    return;
3989                } else {
3990                    // More complicated: need to keep all affiliated tasks together.
3991                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
3992                        // All went well.
3993                        return;
3994                    }
3995
3996                    // Uh oh...  something bad in the affiliation chain, try to rebuild
3997                    // everything and then go through our general path of adding a new task.
3998                    needAffiliationFix = true;
3999                }
4000            } else {
4001                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4002                needAffiliationFix = true;
4003            }
4004        }
4005
4006        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4007        trimRecentsForTask(task, true);
4008
4009        N = mRecentTasks.size();
4010        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4011            final TaskRecord tr = mRecentTasks.remove(N - 1);
4012            tr.removedFromRecents(mTaskPersister);
4013            N--;
4014        }
4015        task.inRecents = true;
4016        if (!isAffiliated || needAffiliationFix) {
4017            // If this is a simple non-affiliated task, or we had some failure trying to
4018            // handle it as part of an affilated task, then just place it at the top.
4019            mRecentTasks.add(0, task);
4020        } else if (isAffiliated) {
4021            // If this is a new affiliated task, then move all of the affiliated tasks
4022            // to the front and insert this new one.
4023            TaskRecord other = task.mNextAffiliate;
4024            if (other == null) {
4025                other = task.mPrevAffiliate;
4026            }
4027            if (other != null) {
4028                int otherIndex = mRecentTasks.indexOf(other);
4029                if (otherIndex >= 0) {
4030                    // Insert new task at appropriate location.
4031                    int taskIndex;
4032                    if (other == task.mNextAffiliate) {
4033                        // We found the index of our next affiliation, which is who is
4034                        // before us in the list, so add after that point.
4035                        taskIndex = otherIndex+1;
4036                    } else {
4037                        // We found the index of our previous affiliation, which is who is
4038                        // after us in the list, so add at their position.
4039                        taskIndex = otherIndex;
4040                    }
4041                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4042                            + taskIndex + ": " + task);
4043                    mRecentTasks.add(taskIndex, task);
4044
4045                    // Now move everything to the front.
4046                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4047                        // All went well.
4048                        return;
4049                    }
4050
4051                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4052                    // everything and then go through our general path of adding a new task.
4053                    needAffiliationFix = true;
4054                } else {
4055                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4056                            + other);
4057                    needAffiliationFix = true;
4058                }
4059            } else {
4060                if (DEBUG_RECENTS) Slog.d(TAG,
4061                        "addRecent: adding affiliated task without next/prev:" + task);
4062                needAffiliationFix = true;
4063            }
4064        }
4065        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4066
4067        if (needAffiliationFix) {
4068            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4069            cleanupRecentTasksLocked(task.userId);
4070        }
4071    }
4072
4073    /**
4074     * If needed, remove oldest existing entries in recents that are for the same kind
4075     * of task as the given one.
4076     */
4077    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4078        int N = mRecentTasks.size();
4079        final Intent intent = task.intent;
4080        final boolean document = intent != null && intent.isDocument();
4081
4082        int maxRecents = task.maxRecents - 1;
4083        for (int i=0; i<N; i++) {
4084            final TaskRecord tr = mRecentTasks.get(i);
4085            if (task != tr) {
4086                if (task.userId != tr.userId) {
4087                    continue;
4088                }
4089                if (i > MAX_RECENT_BITMAPS) {
4090                    tr.freeLastThumbnail();
4091                }
4092                final Intent trIntent = tr.intent;
4093                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4094                    (intent == null || !intent.filterEquals(trIntent))) {
4095                    continue;
4096                }
4097                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4098                if (document && trIsDocument) {
4099                    // These are the same document activity (not necessarily the same doc).
4100                    if (maxRecents > 0) {
4101                        --maxRecents;
4102                        continue;
4103                    }
4104                    // Hit the maximum number of documents for this task. Fall through
4105                    // and remove this document from recents.
4106                } else if (document || trIsDocument) {
4107                    // Only one of these is a document. Not the droid we're looking for.
4108                    continue;
4109                }
4110            }
4111
4112            if (!doTrim) {
4113                // If the caller is not actually asking for a trim, just tell them we reached
4114                // a point where the trim would happen.
4115                return i;
4116            }
4117
4118            // Either task and tr are the same or, their affinities match or their intents match
4119            // and neither of them is a document, or they are documents using the same activity
4120            // and their maxRecents has been reached.
4121            tr.disposeThumbnail();
4122            mRecentTasks.remove(i);
4123            if (task != tr) {
4124                tr.removedFromRecents(mTaskPersister);
4125            }
4126            i--;
4127            N--;
4128            if (task.intent == null) {
4129                // If the new recent task we are adding is not fully
4130                // specified, then replace it with the existing recent task.
4131                task = tr;
4132            }
4133            notifyTaskPersisterLocked(tr, false);
4134        }
4135
4136        return -1;
4137    }
4138
4139    @Override
4140    public void reportActivityFullyDrawn(IBinder token) {
4141        synchronized (this) {
4142            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4143            if (r == null) {
4144                return;
4145            }
4146            r.reportFullyDrawnLocked();
4147        }
4148    }
4149
4150    @Override
4151    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4152        synchronized (this) {
4153            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4154            if (r == null) {
4155                return;
4156            }
4157            final long origId = Binder.clearCallingIdentity();
4158            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4159            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4160                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4161            if (config != null) {
4162                r.frozenBeforeDestroy = true;
4163                if (!updateConfigurationLocked(config, r, false, false)) {
4164                    mStackSupervisor.resumeTopActivitiesLocked();
4165                }
4166            }
4167            Binder.restoreCallingIdentity(origId);
4168        }
4169    }
4170
4171    @Override
4172    public int getRequestedOrientation(IBinder token) {
4173        synchronized (this) {
4174            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4175            if (r == null) {
4176                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4177            }
4178            return mWindowManager.getAppOrientation(r.appToken);
4179        }
4180    }
4181
4182    /**
4183     * This is the internal entry point for handling Activity.finish().
4184     *
4185     * @param token The Binder token referencing the Activity we want to finish.
4186     * @param resultCode Result code, if any, from this Activity.
4187     * @param resultData Result data (Intent), if any, from this Activity.
4188     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4189     *            the root Activity in the task.
4190     *
4191     * @return Returns true if the activity successfully finished, or false if it is still running.
4192     */
4193    @Override
4194    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4195            boolean finishTask) {
4196        // Refuse possible leaked file descriptors
4197        if (resultData != null && resultData.hasFileDescriptors() == true) {
4198            throw new IllegalArgumentException("File descriptors passed in Intent");
4199        }
4200
4201        synchronized(this) {
4202            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4203            if (r == null) {
4204                return true;
4205            }
4206            // Keep track of the root activity of the task before we finish it
4207            TaskRecord tr = r.task;
4208            ActivityRecord rootR = tr.getRootActivity();
4209            if (rootR == null) {
4210                Slog.w(TAG, "Finishing task with all activities already finished");
4211            }
4212            // Do not allow task to finish in Lock Task mode.
4213            if (tr == mStackSupervisor.mLockTaskModeTask) {
4214                if (rootR == r) {
4215                    Slog.i(TAG, "Not finishing task in lock task mode");
4216                    mStackSupervisor.showLockTaskToast();
4217                    return false;
4218                }
4219            }
4220            if (mController != null) {
4221                // Find the first activity that is not finishing.
4222                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4223                if (next != null) {
4224                    // ask watcher if this is allowed
4225                    boolean resumeOK = true;
4226                    try {
4227                        resumeOK = mController.activityResuming(next.packageName);
4228                    } catch (RemoteException e) {
4229                        mController = null;
4230                        Watchdog.getInstance().setActivityController(null);
4231                    }
4232
4233                    if (!resumeOK) {
4234                        Slog.i(TAG, "Not finishing activity because controller resumed");
4235                        return false;
4236                    }
4237                }
4238            }
4239            final long origId = Binder.clearCallingIdentity();
4240            try {
4241                boolean res;
4242                if (finishTask && r == rootR) {
4243                    // If requested, remove the task that is associated to this activity only if it
4244                    // was the root activity in the task. The result code and data is ignored
4245                    // because we don't support returning them across task boundaries.
4246                    res = removeTaskByIdLocked(tr.taskId, false);
4247                    if (!res) {
4248                        Slog.i(TAG, "Removing task failed to finish activity");
4249                    }
4250                } else {
4251                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4252                            resultData, "app-request", true);
4253                    if (!res) {
4254                        Slog.i(TAG, "Failed to finish by app-request");
4255                    }
4256                }
4257                return res;
4258            } finally {
4259                Binder.restoreCallingIdentity(origId);
4260            }
4261        }
4262    }
4263
4264    @Override
4265    public final void finishHeavyWeightApp() {
4266        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4267                != PackageManager.PERMISSION_GRANTED) {
4268            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4269                    + Binder.getCallingPid()
4270                    + ", uid=" + Binder.getCallingUid()
4271                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4272            Slog.w(TAG, msg);
4273            throw new SecurityException(msg);
4274        }
4275
4276        synchronized(this) {
4277            if (mHeavyWeightProcess == null) {
4278                return;
4279            }
4280
4281            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4282                    mHeavyWeightProcess.activities);
4283            for (int i=0; i<activities.size(); i++) {
4284                ActivityRecord r = activities.get(i);
4285                if (!r.finishing) {
4286                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4287                            null, "finish-heavy", true);
4288                }
4289            }
4290
4291            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4292                    mHeavyWeightProcess.userId, 0));
4293            mHeavyWeightProcess = null;
4294        }
4295    }
4296
4297    @Override
4298    public void crashApplication(int uid, int initialPid, String packageName,
4299            String message) {
4300        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4301                != PackageManager.PERMISSION_GRANTED) {
4302            String msg = "Permission Denial: crashApplication() from pid="
4303                    + Binder.getCallingPid()
4304                    + ", uid=" + Binder.getCallingUid()
4305                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4306            Slog.w(TAG, msg);
4307            throw new SecurityException(msg);
4308        }
4309
4310        synchronized(this) {
4311            ProcessRecord proc = null;
4312
4313            // Figure out which process to kill.  We don't trust that initialPid
4314            // still has any relation to current pids, so must scan through the
4315            // list.
4316            synchronized (mPidsSelfLocked) {
4317                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4318                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4319                    if (p.uid != uid) {
4320                        continue;
4321                    }
4322                    if (p.pid == initialPid) {
4323                        proc = p;
4324                        break;
4325                    }
4326                    if (p.pkgList.containsKey(packageName)) {
4327                        proc = p;
4328                    }
4329                }
4330            }
4331
4332            if (proc == null) {
4333                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4334                        + " initialPid=" + initialPid
4335                        + " packageName=" + packageName);
4336                return;
4337            }
4338
4339            if (proc.thread != null) {
4340                if (proc.pid == Process.myPid()) {
4341                    Log.w(TAG, "crashApplication: trying to crash self!");
4342                    return;
4343                }
4344                long ident = Binder.clearCallingIdentity();
4345                try {
4346                    proc.thread.scheduleCrash(message);
4347                } catch (RemoteException e) {
4348                }
4349                Binder.restoreCallingIdentity(ident);
4350            }
4351        }
4352    }
4353
4354    @Override
4355    public final void finishSubActivity(IBinder token, String resultWho,
4356            int requestCode) {
4357        synchronized(this) {
4358            final long origId = Binder.clearCallingIdentity();
4359            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4360            if (r != null) {
4361                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4362            }
4363            Binder.restoreCallingIdentity(origId);
4364        }
4365    }
4366
4367    @Override
4368    public boolean finishActivityAffinity(IBinder token) {
4369        synchronized(this) {
4370            final long origId = Binder.clearCallingIdentity();
4371            try {
4372                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4373
4374                ActivityRecord rootR = r.task.getRootActivity();
4375                // Do not allow task to finish in Lock Task mode.
4376                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4377                    if (rootR == r) {
4378                        mStackSupervisor.showLockTaskToast();
4379                        return false;
4380                    }
4381                }
4382                boolean res = false;
4383                if (r != null) {
4384                    res = r.task.stack.finishActivityAffinityLocked(r);
4385                }
4386                return res;
4387            } finally {
4388                Binder.restoreCallingIdentity(origId);
4389            }
4390        }
4391    }
4392
4393    @Override
4394    public void finishVoiceTask(IVoiceInteractionSession session) {
4395        synchronized(this) {
4396            final long origId = Binder.clearCallingIdentity();
4397            try {
4398                mStackSupervisor.finishVoiceTask(session);
4399            } finally {
4400                Binder.restoreCallingIdentity(origId);
4401            }
4402        }
4403
4404    }
4405
4406    @Override
4407    public boolean releaseActivityInstance(IBinder token) {
4408        synchronized(this) {
4409            final long origId = Binder.clearCallingIdentity();
4410            try {
4411                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4412                if (r.task == null || r.task.stack == null) {
4413                    return false;
4414                }
4415                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4416            } finally {
4417                Binder.restoreCallingIdentity(origId);
4418            }
4419        }
4420    }
4421
4422    @Override
4423    public void releaseSomeActivities(IApplicationThread appInt) {
4424        synchronized(this) {
4425            final long origId = Binder.clearCallingIdentity();
4426            try {
4427                ProcessRecord app = getRecordForAppLocked(appInt);
4428                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4429            } finally {
4430                Binder.restoreCallingIdentity(origId);
4431            }
4432        }
4433    }
4434
4435    @Override
4436    public boolean willActivityBeVisible(IBinder token) {
4437        synchronized(this) {
4438            ActivityStack stack = ActivityRecord.getStackLocked(token);
4439            if (stack != null) {
4440                return stack.willActivityBeVisibleLocked(token);
4441            }
4442            return false;
4443        }
4444    }
4445
4446    @Override
4447    public void overridePendingTransition(IBinder token, String packageName,
4448            int enterAnim, int exitAnim) {
4449        synchronized(this) {
4450            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4451            if (self == null) {
4452                return;
4453            }
4454
4455            final long origId = Binder.clearCallingIdentity();
4456
4457            if (self.state == ActivityState.RESUMED
4458                    || self.state == ActivityState.PAUSING) {
4459                mWindowManager.overridePendingAppTransition(packageName,
4460                        enterAnim, exitAnim, null);
4461            }
4462
4463            Binder.restoreCallingIdentity(origId);
4464        }
4465    }
4466
4467    /**
4468     * Main function for removing an existing process from the activity manager
4469     * as a result of that process going away.  Clears out all connections
4470     * to the process.
4471     */
4472    private final void handleAppDiedLocked(ProcessRecord app,
4473            boolean restarting, boolean allowRestart) {
4474        int pid = app.pid;
4475        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4476        if (!kept && !restarting) {
4477            removeLruProcessLocked(app);
4478            if (pid > 0) {
4479                ProcessList.remove(pid);
4480            }
4481        }
4482
4483        if (mProfileProc == app) {
4484            clearProfilerLocked();
4485        }
4486
4487        // Remove this application's activities from active lists.
4488        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4489
4490        app.activities.clear();
4491
4492        if (app.instrumentationClass != null) {
4493            Slog.w(TAG, "Crash of app " + app.processName
4494                  + " running instrumentation " + app.instrumentationClass);
4495            Bundle info = new Bundle();
4496            info.putString("shortMsg", "Process crashed.");
4497            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4498        }
4499
4500        if (!restarting) {
4501            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4502                // If there was nothing to resume, and we are not already
4503                // restarting this process, but there is a visible activity that
4504                // is hosted by the process...  then make sure all visible
4505                // activities are running, taking care of restarting this
4506                // process.
4507                if (hasVisibleActivities) {
4508                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4509                }
4510            }
4511        }
4512    }
4513
4514    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4515        IBinder threadBinder = thread.asBinder();
4516        // Find the application record.
4517        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4518            ProcessRecord rec = mLruProcesses.get(i);
4519            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4520                return i;
4521            }
4522        }
4523        return -1;
4524    }
4525
4526    final ProcessRecord getRecordForAppLocked(
4527            IApplicationThread thread) {
4528        if (thread == null) {
4529            return null;
4530        }
4531
4532        int appIndex = getLRURecordIndexForAppLocked(thread);
4533        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4534    }
4535
4536    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4537        // If there are no longer any background processes running,
4538        // and the app that died was not running instrumentation,
4539        // then tell everyone we are now low on memory.
4540        boolean haveBg = false;
4541        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4542            ProcessRecord rec = mLruProcesses.get(i);
4543            if (rec.thread != null
4544                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4545                haveBg = true;
4546                break;
4547            }
4548        }
4549
4550        if (!haveBg) {
4551            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4552            if (doReport) {
4553                long now = SystemClock.uptimeMillis();
4554                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4555                    doReport = false;
4556                } else {
4557                    mLastMemUsageReportTime = now;
4558                }
4559            }
4560            final ArrayList<ProcessMemInfo> memInfos
4561                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4562            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4563            long now = SystemClock.uptimeMillis();
4564            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4565                ProcessRecord rec = mLruProcesses.get(i);
4566                if (rec == dyingProc || rec.thread == null) {
4567                    continue;
4568                }
4569                if (doReport) {
4570                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4571                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4572                }
4573                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4574                    // The low memory report is overriding any current
4575                    // state for a GC request.  Make sure to do
4576                    // heavy/important/visible/foreground processes first.
4577                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4578                        rec.lastRequestedGc = 0;
4579                    } else {
4580                        rec.lastRequestedGc = rec.lastLowMemory;
4581                    }
4582                    rec.reportLowMemory = true;
4583                    rec.lastLowMemory = now;
4584                    mProcessesToGc.remove(rec);
4585                    addProcessToGcListLocked(rec);
4586                }
4587            }
4588            if (doReport) {
4589                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4590                mHandler.sendMessage(msg);
4591            }
4592            scheduleAppGcsLocked();
4593        }
4594    }
4595
4596    final void appDiedLocked(ProcessRecord app) {
4597       appDiedLocked(app, app.pid, app.thread);
4598    }
4599
4600    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4601        // First check if this ProcessRecord is actually active for the pid.
4602        synchronized (mPidsSelfLocked) {
4603            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4604            if (curProc != app) {
4605                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4606                return;
4607            }
4608        }
4609
4610        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4611        synchronized (stats) {
4612            stats.noteProcessDiedLocked(app.info.uid, pid);
4613        }
4614
4615        Process.killProcessQuiet(pid);
4616        Process.killProcessGroup(app.info.uid, pid);
4617        app.killed = true;
4618
4619        // Clean up already done if the process has been re-started.
4620        if (app.pid == pid && app.thread != null &&
4621                app.thread.asBinder() == thread.asBinder()) {
4622            boolean doLowMem = app.instrumentationClass == null;
4623            boolean doOomAdj = doLowMem;
4624            if (!app.killedByAm) {
4625                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4626                        + ") has died");
4627                mAllowLowerMemLevel = true;
4628            } else {
4629                // Note that we always want to do oom adj to update our state with the
4630                // new number of procs.
4631                mAllowLowerMemLevel = false;
4632                doLowMem = false;
4633            }
4634            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4635            if (DEBUG_CLEANUP) Slog.v(
4636                TAG, "Dying app: " + app + ", pid: " + pid
4637                + ", thread: " + thread.asBinder());
4638            handleAppDiedLocked(app, false, true);
4639
4640            if (doOomAdj) {
4641                updateOomAdjLocked();
4642            }
4643            if (doLowMem) {
4644                doLowMemReportIfNeededLocked(app);
4645            }
4646        } else if (app.pid != pid) {
4647            // A new process has already been started.
4648            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4649                    + ") has died and restarted (pid " + app.pid + ").");
4650            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4651        } else if (DEBUG_PROCESSES) {
4652            Slog.d(TAG, "Received spurious death notification for thread "
4653                    + thread.asBinder());
4654        }
4655    }
4656
4657    /**
4658     * If a stack trace dump file is configured, dump process stack traces.
4659     * @param clearTraces causes the dump file to be erased prior to the new
4660     *    traces being written, if true; when false, the new traces will be
4661     *    appended to any existing file content.
4662     * @param firstPids of dalvik VM processes to dump stack traces for first
4663     * @param lastPids of dalvik VM processes to dump stack traces for last
4664     * @param nativeProcs optional list of native process names to dump stack crawls
4665     * @return file containing stack traces, or null if no dump file is configured
4666     */
4667    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4668            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4669        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4670        if (tracesPath == null || tracesPath.length() == 0) {
4671            return null;
4672        }
4673
4674        File tracesFile = new File(tracesPath);
4675        try {
4676            File tracesDir = tracesFile.getParentFile();
4677            if (!tracesDir.exists()) {
4678                tracesDir.mkdirs();
4679                if (!SELinux.restorecon(tracesDir)) {
4680                    return null;
4681                }
4682            }
4683            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4684
4685            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4686            tracesFile.createNewFile();
4687            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4688        } catch (IOException e) {
4689            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4690            return null;
4691        }
4692
4693        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4694        return tracesFile;
4695    }
4696
4697    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4698            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4699        // Use a FileObserver to detect when traces finish writing.
4700        // The order of traces is considered important to maintain for legibility.
4701        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4702            @Override
4703            public synchronized void onEvent(int event, String path) { notify(); }
4704        };
4705
4706        try {
4707            observer.startWatching();
4708
4709            // First collect all of the stacks of the most important pids.
4710            if (firstPids != null) {
4711                try {
4712                    int num = firstPids.size();
4713                    for (int i = 0; i < num; i++) {
4714                        synchronized (observer) {
4715                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4716                            observer.wait(200);  // Wait for write-close, give up after 200msec
4717                        }
4718                    }
4719                } catch (InterruptedException e) {
4720                    Slog.wtf(TAG, e);
4721                }
4722            }
4723
4724            // Next collect the stacks of the native pids
4725            if (nativeProcs != null) {
4726                int[] pids = Process.getPidsForCommands(nativeProcs);
4727                if (pids != null) {
4728                    for (int pid : pids) {
4729                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4730                    }
4731                }
4732            }
4733
4734            // Lastly, measure CPU usage.
4735            if (processCpuTracker != null) {
4736                processCpuTracker.init();
4737                System.gc();
4738                processCpuTracker.update();
4739                try {
4740                    synchronized (processCpuTracker) {
4741                        processCpuTracker.wait(500); // measure over 1/2 second.
4742                    }
4743                } catch (InterruptedException e) {
4744                }
4745                processCpuTracker.update();
4746
4747                // We'll take the stack crawls of just the top apps using CPU.
4748                final int N = processCpuTracker.countWorkingStats();
4749                int numProcs = 0;
4750                for (int i=0; i<N && numProcs<5; i++) {
4751                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4752                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4753                        numProcs++;
4754                        try {
4755                            synchronized (observer) {
4756                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4757                                observer.wait(200);  // Wait for write-close, give up after 200msec
4758                            }
4759                        } catch (InterruptedException e) {
4760                            Slog.wtf(TAG, e);
4761                        }
4762
4763                    }
4764                }
4765            }
4766        } finally {
4767            observer.stopWatching();
4768        }
4769    }
4770
4771    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4772        if (true || IS_USER_BUILD) {
4773            return;
4774        }
4775        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4776        if (tracesPath == null || tracesPath.length() == 0) {
4777            return;
4778        }
4779
4780        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4781        StrictMode.allowThreadDiskWrites();
4782        try {
4783            final File tracesFile = new File(tracesPath);
4784            final File tracesDir = tracesFile.getParentFile();
4785            final File tracesTmp = new File(tracesDir, "__tmp__");
4786            try {
4787                if (!tracesDir.exists()) {
4788                    tracesDir.mkdirs();
4789                    if (!SELinux.restorecon(tracesDir.getPath())) {
4790                        return;
4791                    }
4792                }
4793                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4794
4795                if (tracesFile.exists()) {
4796                    tracesTmp.delete();
4797                    tracesFile.renameTo(tracesTmp);
4798                }
4799                StringBuilder sb = new StringBuilder();
4800                Time tobj = new Time();
4801                tobj.set(System.currentTimeMillis());
4802                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4803                sb.append(": ");
4804                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4805                sb.append(" since ");
4806                sb.append(msg);
4807                FileOutputStream fos = new FileOutputStream(tracesFile);
4808                fos.write(sb.toString().getBytes());
4809                if (app == null) {
4810                    fos.write("\n*** No application process!".getBytes());
4811                }
4812                fos.close();
4813                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4814            } catch (IOException e) {
4815                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4816                return;
4817            }
4818
4819            if (app != null) {
4820                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4821                firstPids.add(app.pid);
4822                dumpStackTraces(tracesPath, firstPids, null, null, null);
4823            }
4824
4825            File lastTracesFile = null;
4826            File curTracesFile = null;
4827            for (int i=9; i>=0; i--) {
4828                String name = String.format(Locale.US, "slow%02d.txt", i);
4829                curTracesFile = new File(tracesDir, name);
4830                if (curTracesFile.exists()) {
4831                    if (lastTracesFile != null) {
4832                        curTracesFile.renameTo(lastTracesFile);
4833                    } else {
4834                        curTracesFile.delete();
4835                    }
4836                }
4837                lastTracesFile = curTracesFile;
4838            }
4839            tracesFile.renameTo(curTracesFile);
4840            if (tracesTmp.exists()) {
4841                tracesTmp.renameTo(tracesFile);
4842            }
4843        } finally {
4844            StrictMode.setThreadPolicy(oldPolicy);
4845        }
4846    }
4847
4848    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4849            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4850        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4851        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4852
4853        if (mController != null) {
4854            try {
4855                // 0 == continue, -1 = kill process immediately
4856                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4857                if (res < 0 && app.pid != MY_PID) {
4858                    app.kill("anr", true);
4859                }
4860            } catch (RemoteException e) {
4861                mController = null;
4862                Watchdog.getInstance().setActivityController(null);
4863            }
4864        }
4865
4866        long anrTime = SystemClock.uptimeMillis();
4867        if (MONITOR_CPU_USAGE) {
4868            updateCpuStatsNow();
4869        }
4870
4871        synchronized (this) {
4872            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4873            if (mShuttingDown) {
4874                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4875                return;
4876            } else if (app.notResponding) {
4877                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4878                return;
4879            } else if (app.crashing) {
4880                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4881                return;
4882            }
4883
4884            // In case we come through here for the same app before completing
4885            // this one, mark as anring now so we will bail out.
4886            app.notResponding = true;
4887
4888            // Log the ANR to the event log.
4889            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4890                    app.processName, app.info.flags, annotation);
4891
4892            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4893            firstPids.add(app.pid);
4894
4895            int parentPid = app.pid;
4896            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4897            if (parentPid != app.pid) firstPids.add(parentPid);
4898
4899            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4900
4901            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4902                ProcessRecord r = mLruProcesses.get(i);
4903                if (r != null && r.thread != null) {
4904                    int pid = r.pid;
4905                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4906                        if (r.persistent) {
4907                            firstPids.add(pid);
4908                        } else {
4909                            lastPids.put(pid, Boolean.TRUE);
4910                        }
4911                    }
4912                }
4913            }
4914        }
4915
4916        // Log the ANR to the main log.
4917        StringBuilder info = new StringBuilder();
4918        info.setLength(0);
4919        info.append("ANR in ").append(app.processName);
4920        if (activity != null && activity.shortComponentName != null) {
4921            info.append(" (").append(activity.shortComponentName).append(")");
4922        }
4923        info.append("\n");
4924        info.append("PID: ").append(app.pid).append("\n");
4925        if (annotation != null) {
4926            info.append("Reason: ").append(annotation).append("\n");
4927        }
4928        if (parent != null && parent != activity) {
4929            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4930        }
4931
4932        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4933
4934        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4935                NATIVE_STACKS_OF_INTEREST);
4936
4937        String cpuInfo = null;
4938        if (MONITOR_CPU_USAGE) {
4939            updateCpuStatsNow();
4940            synchronized (mProcessCpuTracker) {
4941                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4942            }
4943            info.append(processCpuTracker.printCurrentLoad());
4944            info.append(cpuInfo);
4945        }
4946
4947        info.append(processCpuTracker.printCurrentState(anrTime));
4948
4949        Slog.e(TAG, info.toString());
4950        if (tracesFile == null) {
4951            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4952            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4953        }
4954
4955        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4956                cpuInfo, tracesFile, null);
4957
4958        if (mController != null) {
4959            try {
4960                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4961                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4962                if (res != 0) {
4963                    if (res < 0 && app.pid != MY_PID) {
4964                        app.kill("anr", true);
4965                    } else {
4966                        synchronized (this) {
4967                            mServices.scheduleServiceTimeoutLocked(app);
4968                        }
4969                    }
4970                    return;
4971                }
4972            } catch (RemoteException e) {
4973                mController = null;
4974                Watchdog.getInstance().setActivityController(null);
4975            }
4976        }
4977
4978        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4979        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4980                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4981
4982        synchronized (this) {
4983            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4984                app.kill("bg anr", true);
4985                return;
4986            }
4987
4988            // Set the app's notResponding state, and look up the errorReportReceiver
4989            makeAppNotRespondingLocked(app,
4990                    activity != null ? activity.shortComponentName : null,
4991                    annotation != null ? "ANR " + annotation : "ANR",
4992                    info.toString());
4993
4994            // Bring up the infamous App Not Responding dialog
4995            Message msg = Message.obtain();
4996            HashMap<String, Object> map = new HashMap<String, Object>();
4997            msg.what = SHOW_NOT_RESPONDING_MSG;
4998            msg.obj = map;
4999            msg.arg1 = aboveSystem ? 1 : 0;
5000            map.put("app", app);
5001            if (activity != null) {
5002                map.put("activity", activity);
5003            }
5004
5005            mHandler.sendMessage(msg);
5006        }
5007    }
5008
5009    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5010        if (!mLaunchWarningShown) {
5011            mLaunchWarningShown = true;
5012            mHandler.post(new Runnable() {
5013                @Override
5014                public void run() {
5015                    synchronized (ActivityManagerService.this) {
5016                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5017                        d.show();
5018                        mHandler.postDelayed(new Runnable() {
5019                            @Override
5020                            public void run() {
5021                                synchronized (ActivityManagerService.this) {
5022                                    d.dismiss();
5023                                    mLaunchWarningShown = false;
5024                                }
5025                            }
5026                        }, 4000);
5027                    }
5028                }
5029            });
5030        }
5031    }
5032
5033    @Override
5034    public boolean clearApplicationUserData(final String packageName,
5035            final IPackageDataObserver observer, int userId) {
5036        enforceNotIsolatedCaller("clearApplicationUserData");
5037        int uid = Binder.getCallingUid();
5038        int pid = Binder.getCallingPid();
5039        userId = handleIncomingUser(pid, uid,
5040                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5041        long callingId = Binder.clearCallingIdentity();
5042        try {
5043            IPackageManager pm = AppGlobals.getPackageManager();
5044            int pkgUid = -1;
5045            synchronized(this) {
5046                try {
5047                    pkgUid = pm.getPackageUid(packageName, userId);
5048                } catch (RemoteException e) {
5049                }
5050                if (pkgUid == -1) {
5051                    Slog.w(TAG, "Invalid packageName: " + packageName);
5052                    if (observer != null) {
5053                        try {
5054                            observer.onRemoveCompleted(packageName, false);
5055                        } catch (RemoteException e) {
5056                            Slog.i(TAG, "Observer no longer exists.");
5057                        }
5058                    }
5059                    return false;
5060                }
5061                if (uid == pkgUid || checkComponentPermission(
5062                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5063                        pid, uid, -1, true)
5064                        == PackageManager.PERMISSION_GRANTED) {
5065                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5066                } else {
5067                    throw new SecurityException("PID " + pid + " does not have permission "
5068                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5069                                    + " of package " + packageName);
5070                }
5071
5072                // Remove all tasks match the cleared application package and user
5073                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5074                    final TaskRecord tr = mRecentTasks.get(i);
5075                    final String taskPackageName =
5076                            tr.getBaseIntent().getComponent().getPackageName();
5077                    if (tr.userId != userId) continue;
5078                    if (!taskPackageName.equals(packageName)) continue;
5079                    removeTaskByIdLocked(tr.taskId, false);
5080                }
5081            }
5082
5083            try {
5084                // Clear application user data
5085                pm.clearApplicationUserData(packageName, observer, userId);
5086
5087                synchronized(this) {
5088                    // Remove all permissions granted from/to this package
5089                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5090                }
5091
5092                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5093                        Uri.fromParts("package", packageName, null));
5094                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5095                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5096                        null, null, 0, null, null, null, false, false, userId);
5097            } catch (RemoteException e) {
5098            }
5099        } finally {
5100            Binder.restoreCallingIdentity(callingId);
5101        }
5102        return true;
5103    }
5104
5105    @Override
5106    public void killBackgroundProcesses(final String packageName, int userId) {
5107        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5108                != PackageManager.PERMISSION_GRANTED &&
5109                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5110                        != PackageManager.PERMISSION_GRANTED) {
5111            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5112                    + Binder.getCallingPid()
5113                    + ", uid=" + Binder.getCallingUid()
5114                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5115            Slog.w(TAG, msg);
5116            throw new SecurityException(msg);
5117        }
5118
5119        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5120                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5121        long callingId = Binder.clearCallingIdentity();
5122        try {
5123            IPackageManager pm = AppGlobals.getPackageManager();
5124            synchronized(this) {
5125                int appId = -1;
5126                try {
5127                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5128                } catch (RemoteException e) {
5129                }
5130                if (appId == -1) {
5131                    Slog.w(TAG, "Invalid packageName: " + packageName);
5132                    return;
5133                }
5134                killPackageProcessesLocked(packageName, appId, userId,
5135                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5136            }
5137        } finally {
5138            Binder.restoreCallingIdentity(callingId);
5139        }
5140    }
5141
5142    @Override
5143    public void killAllBackgroundProcesses() {
5144        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5145                != PackageManager.PERMISSION_GRANTED) {
5146            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5147                    + Binder.getCallingPid()
5148                    + ", uid=" + Binder.getCallingUid()
5149                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5150            Slog.w(TAG, msg);
5151            throw new SecurityException(msg);
5152        }
5153
5154        long callingId = Binder.clearCallingIdentity();
5155        try {
5156            synchronized(this) {
5157                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5158                final int NP = mProcessNames.getMap().size();
5159                for (int ip=0; ip<NP; ip++) {
5160                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5161                    final int NA = apps.size();
5162                    for (int ia=0; ia<NA; ia++) {
5163                        ProcessRecord app = apps.valueAt(ia);
5164                        if (app.persistent) {
5165                            // we don't kill persistent processes
5166                            continue;
5167                        }
5168                        if (app.removed) {
5169                            procs.add(app);
5170                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5171                            app.removed = true;
5172                            procs.add(app);
5173                        }
5174                    }
5175                }
5176
5177                int N = procs.size();
5178                for (int i=0; i<N; i++) {
5179                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5180                }
5181                mAllowLowerMemLevel = true;
5182                updateOomAdjLocked();
5183                doLowMemReportIfNeededLocked(null);
5184            }
5185        } finally {
5186            Binder.restoreCallingIdentity(callingId);
5187        }
5188    }
5189
5190    @Override
5191    public void forceStopPackage(final String packageName, int userId) {
5192        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5193                != PackageManager.PERMISSION_GRANTED) {
5194            String msg = "Permission Denial: forceStopPackage() from pid="
5195                    + Binder.getCallingPid()
5196                    + ", uid=" + Binder.getCallingUid()
5197                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5198            Slog.w(TAG, msg);
5199            throw new SecurityException(msg);
5200        }
5201        final int callingPid = Binder.getCallingPid();
5202        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5203                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5204        long callingId = Binder.clearCallingIdentity();
5205        try {
5206            IPackageManager pm = AppGlobals.getPackageManager();
5207            synchronized(this) {
5208                int[] users = userId == UserHandle.USER_ALL
5209                        ? getUsersLocked() : new int[] { userId };
5210                for (int user : users) {
5211                    int pkgUid = -1;
5212                    try {
5213                        pkgUid = pm.getPackageUid(packageName, user);
5214                    } catch (RemoteException e) {
5215                    }
5216                    if (pkgUid == -1) {
5217                        Slog.w(TAG, "Invalid packageName: " + packageName);
5218                        continue;
5219                    }
5220                    try {
5221                        pm.setPackageStoppedState(packageName, true, user);
5222                    } catch (RemoteException e) {
5223                    } catch (IllegalArgumentException e) {
5224                        Slog.w(TAG, "Failed trying to unstop package "
5225                                + packageName + ": " + e);
5226                    }
5227                    if (isUserRunningLocked(user, false)) {
5228                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5229                    }
5230                }
5231            }
5232        } finally {
5233            Binder.restoreCallingIdentity(callingId);
5234        }
5235    }
5236
5237    @Override
5238    public void addPackageDependency(String packageName) {
5239        synchronized (this) {
5240            int callingPid = Binder.getCallingPid();
5241            if (callingPid == Process.myPid()) {
5242                //  Yeah, um, no.
5243                Slog.w(TAG, "Can't addPackageDependency on system process");
5244                return;
5245            }
5246            ProcessRecord proc;
5247            synchronized (mPidsSelfLocked) {
5248                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5249            }
5250            if (proc != null) {
5251                if (proc.pkgDeps == null) {
5252                    proc.pkgDeps = new ArraySet<String>(1);
5253                }
5254                proc.pkgDeps.add(packageName);
5255            }
5256        }
5257    }
5258
5259    /*
5260     * The pkg name and app id have to be specified.
5261     */
5262    @Override
5263    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5264        if (pkg == null) {
5265            return;
5266        }
5267        // Make sure the uid is valid.
5268        if (appid < 0) {
5269            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5270            return;
5271        }
5272        int callerUid = Binder.getCallingUid();
5273        // Only the system server can kill an application
5274        if (callerUid == Process.SYSTEM_UID) {
5275            // Post an aysnc message to kill the application
5276            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5277            msg.arg1 = appid;
5278            msg.arg2 = 0;
5279            Bundle bundle = new Bundle();
5280            bundle.putString("pkg", pkg);
5281            bundle.putString("reason", reason);
5282            msg.obj = bundle;
5283            mHandler.sendMessage(msg);
5284        } else {
5285            throw new SecurityException(callerUid + " cannot kill pkg: " +
5286                    pkg);
5287        }
5288    }
5289
5290    @Override
5291    public void closeSystemDialogs(String reason) {
5292        enforceNotIsolatedCaller("closeSystemDialogs");
5293
5294        final int pid = Binder.getCallingPid();
5295        final int uid = Binder.getCallingUid();
5296        final long origId = Binder.clearCallingIdentity();
5297        try {
5298            synchronized (this) {
5299                // Only allow this from foreground processes, so that background
5300                // applications can't abuse it to prevent system UI from being shown.
5301                if (uid >= Process.FIRST_APPLICATION_UID) {
5302                    ProcessRecord proc;
5303                    synchronized (mPidsSelfLocked) {
5304                        proc = mPidsSelfLocked.get(pid);
5305                    }
5306                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5307                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5308                                + " from background process " + proc);
5309                        return;
5310                    }
5311                }
5312                closeSystemDialogsLocked(reason);
5313            }
5314        } finally {
5315            Binder.restoreCallingIdentity(origId);
5316        }
5317    }
5318
5319    void closeSystemDialogsLocked(String reason) {
5320        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5321        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5322                | Intent.FLAG_RECEIVER_FOREGROUND);
5323        if (reason != null) {
5324            intent.putExtra("reason", reason);
5325        }
5326        mWindowManager.closeSystemDialogs(reason);
5327
5328        mStackSupervisor.closeSystemDialogsLocked();
5329
5330        broadcastIntentLocked(null, null, intent, null,
5331                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5332                Process.SYSTEM_UID, UserHandle.USER_ALL);
5333    }
5334
5335    @Override
5336    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5337        enforceNotIsolatedCaller("getProcessMemoryInfo");
5338        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5339        for (int i=pids.length-1; i>=0; i--) {
5340            ProcessRecord proc;
5341            int oomAdj;
5342            synchronized (this) {
5343                synchronized (mPidsSelfLocked) {
5344                    proc = mPidsSelfLocked.get(pids[i]);
5345                    oomAdj = proc != null ? proc.setAdj : 0;
5346                }
5347            }
5348            infos[i] = new Debug.MemoryInfo();
5349            Debug.getMemoryInfo(pids[i], infos[i]);
5350            if (proc != null) {
5351                synchronized (this) {
5352                    if (proc.thread != null && proc.setAdj == oomAdj) {
5353                        // Record this for posterity if the process has been stable.
5354                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5355                                infos[i].getTotalUss(), false, proc.pkgList);
5356                    }
5357                }
5358            }
5359        }
5360        return infos;
5361    }
5362
5363    @Override
5364    public long[] getProcessPss(int[] pids) {
5365        enforceNotIsolatedCaller("getProcessPss");
5366        long[] pss = new long[pids.length];
5367        for (int i=pids.length-1; i>=0; i--) {
5368            ProcessRecord proc;
5369            int oomAdj;
5370            synchronized (this) {
5371                synchronized (mPidsSelfLocked) {
5372                    proc = mPidsSelfLocked.get(pids[i]);
5373                    oomAdj = proc != null ? proc.setAdj : 0;
5374                }
5375            }
5376            long[] tmpUss = new long[1];
5377            pss[i] = Debug.getPss(pids[i], tmpUss);
5378            if (proc != null) {
5379                synchronized (this) {
5380                    if (proc.thread != null && proc.setAdj == oomAdj) {
5381                        // Record this for posterity if the process has been stable.
5382                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5383                    }
5384                }
5385            }
5386        }
5387        return pss;
5388    }
5389
5390    @Override
5391    public void killApplicationProcess(String processName, int uid) {
5392        if (processName == null) {
5393            return;
5394        }
5395
5396        int callerUid = Binder.getCallingUid();
5397        // Only the system server can kill an application
5398        if (callerUid == Process.SYSTEM_UID) {
5399            synchronized (this) {
5400                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5401                if (app != null && app.thread != null) {
5402                    try {
5403                        app.thread.scheduleSuicide();
5404                    } catch (RemoteException e) {
5405                        // If the other end already died, then our work here is done.
5406                    }
5407                } else {
5408                    Slog.w(TAG, "Process/uid not found attempting kill of "
5409                            + processName + " / " + uid);
5410                }
5411            }
5412        } else {
5413            throw new SecurityException(callerUid + " cannot kill app process: " +
5414                    processName);
5415        }
5416    }
5417
5418    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5419        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5420                false, true, false, false, UserHandle.getUserId(uid), reason);
5421        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5422                Uri.fromParts("package", packageName, null));
5423        if (!mProcessesReady) {
5424            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5425                    | Intent.FLAG_RECEIVER_FOREGROUND);
5426        }
5427        intent.putExtra(Intent.EXTRA_UID, uid);
5428        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5429        broadcastIntentLocked(null, null, intent,
5430                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5431                false, false,
5432                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5433    }
5434
5435    private void forceStopUserLocked(int userId, String reason) {
5436        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5437        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5438        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5439                | Intent.FLAG_RECEIVER_FOREGROUND);
5440        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5441        broadcastIntentLocked(null, null, intent,
5442                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5443                false, false,
5444                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5445    }
5446
5447    private final boolean killPackageProcessesLocked(String packageName, int appId,
5448            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5449            boolean doit, boolean evenPersistent, String reason) {
5450        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5451
5452        // Remove all processes this package may have touched: all with the
5453        // same UID (except for the system or root user), and all whose name
5454        // matches the package name.
5455        final int NP = mProcessNames.getMap().size();
5456        for (int ip=0; ip<NP; ip++) {
5457            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5458            final int NA = apps.size();
5459            for (int ia=0; ia<NA; ia++) {
5460                ProcessRecord app = apps.valueAt(ia);
5461                if (app.persistent && !evenPersistent) {
5462                    // we don't kill persistent processes
5463                    continue;
5464                }
5465                if (app.removed) {
5466                    if (doit) {
5467                        procs.add(app);
5468                    }
5469                    continue;
5470                }
5471
5472                // Skip process if it doesn't meet our oom adj requirement.
5473                if (app.setAdj < minOomAdj) {
5474                    continue;
5475                }
5476
5477                // If no package is specified, we call all processes under the
5478                // give user id.
5479                if (packageName == null) {
5480                    if (app.userId != userId) {
5481                        continue;
5482                    }
5483                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5484                        continue;
5485                    }
5486                // Package has been specified, we want to hit all processes
5487                // that match it.  We need to qualify this by the processes
5488                // that are running under the specified app and user ID.
5489                } else {
5490                    final boolean isDep = app.pkgDeps != null
5491                            && app.pkgDeps.contains(packageName);
5492                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5493                        continue;
5494                    }
5495                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5496                        continue;
5497                    }
5498                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5499                        continue;
5500                    }
5501                }
5502
5503                // Process has passed all conditions, kill it!
5504                if (!doit) {
5505                    return true;
5506                }
5507                app.removed = true;
5508                procs.add(app);
5509            }
5510        }
5511
5512        int N = procs.size();
5513        for (int i=0; i<N; i++) {
5514            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5515        }
5516        updateOomAdjLocked();
5517        return N > 0;
5518    }
5519
5520    private final boolean forceStopPackageLocked(String name, int appId,
5521            boolean callerWillRestart, boolean purgeCache, boolean doit,
5522            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5523        int i;
5524        int N;
5525
5526        if (userId == UserHandle.USER_ALL && name == null) {
5527            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5528        }
5529
5530        if (appId < 0 && name != null) {
5531            try {
5532                appId = UserHandle.getAppId(
5533                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5534            } catch (RemoteException e) {
5535            }
5536        }
5537
5538        if (doit) {
5539            if (name != null) {
5540                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5541                        + " user=" + userId + ": " + reason);
5542            } else {
5543                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5544            }
5545
5546            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5547            for (int ip=pmap.size()-1; ip>=0; ip--) {
5548                SparseArray<Long> ba = pmap.valueAt(ip);
5549                for (i=ba.size()-1; i>=0; i--) {
5550                    boolean remove = false;
5551                    final int entUid = ba.keyAt(i);
5552                    if (name != null) {
5553                        if (userId == UserHandle.USER_ALL) {
5554                            if (UserHandle.getAppId(entUid) == appId) {
5555                                remove = true;
5556                            }
5557                        } else {
5558                            if (entUid == UserHandle.getUid(userId, appId)) {
5559                                remove = true;
5560                            }
5561                        }
5562                    } else if (UserHandle.getUserId(entUid) == userId) {
5563                        remove = true;
5564                    }
5565                    if (remove) {
5566                        ba.removeAt(i);
5567                    }
5568                }
5569                if (ba.size() == 0) {
5570                    pmap.removeAt(ip);
5571                }
5572            }
5573        }
5574
5575        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5576                -100, callerWillRestart, true, doit, evenPersistent,
5577                name == null ? ("stop user " + userId) : ("stop " + name));
5578
5579        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5580            if (!doit) {
5581                return true;
5582            }
5583            didSomething = true;
5584        }
5585
5586        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5587            if (!doit) {
5588                return true;
5589            }
5590            didSomething = true;
5591        }
5592
5593        if (name == null) {
5594            // Remove all sticky broadcasts from this user.
5595            mStickyBroadcasts.remove(userId);
5596        }
5597
5598        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5599        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5600                userId, providers)) {
5601            if (!doit) {
5602                return true;
5603            }
5604            didSomething = true;
5605        }
5606        N = providers.size();
5607        for (i=0; i<N; i++) {
5608            removeDyingProviderLocked(null, providers.get(i), true);
5609        }
5610
5611        // Remove transient permissions granted from/to this package/user
5612        removeUriPermissionsForPackageLocked(name, userId, false);
5613
5614        if (name == null || uninstalling) {
5615            // Remove pending intents.  For now we only do this when force
5616            // stopping users, because we have some problems when doing this
5617            // for packages -- app widgets are not currently cleaned up for
5618            // such packages, so they can be left with bad pending intents.
5619            if (mIntentSenderRecords.size() > 0) {
5620                Iterator<WeakReference<PendingIntentRecord>> it
5621                        = mIntentSenderRecords.values().iterator();
5622                while (it.hasNext()) {
5623                    WeakReference<PendingIntentRecord> wpir = it.next();
5624                    if (wpir == null) {
5625                        it.remove();
5626                        continue;
5627                    }
5628                    PendingIntentRecord pir = wpir.get();
5629                    if (pir == null) {
5630                        it.remove();
5631                        continue;
5632                    }
5633                    if (name == null) {
5634                        // Stopping user, remove all objects for the user.
5635                        if (pir.key.userId != userId) {
5636                            // Not the same user, skip it.
5637                            continue;
5638                        }
5639                    } else {
5640                        if (UserHandle.getAppId(pir.uid) != appId) {
5641                            // Different app id, skip it.
5642                            continue;
5643                        }
5644                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5645                            // Different user, skip it.
5646                            continue;
5647                        }
5648                        if (!pir.key.packageName.equals(name)) {
5649                            // Different package, skip it.
5650                            continue;
5651                        }
5652                    }
5653                    if (!doit) {
5654                        return true;
5655                    }
5656                    didSomething = true;
5657                    it.remove();
5658                    pir.canceled = true;
5659                    if (pir.key.activity != null) {
5660                        pir.key.activity.pendingResults.remove(pir.ref);
5661                    }
5662                }
5663            }
5664        }
5665
5666        if (doit) {
5667            if (purgeCache && name != null) {
5668                AttributeCache ac = AttributeCache.instance();
5669                if (ac != null) {
5670                    ac.removePackage(name);
5671                }
5672            }
5673            if (mBooted) {
5674                mStackSupervisor.resumeTopActivitiesLocked();
5675                mStackSupervisor.scheduleIdleLocked();
5676            }
5677        }
5678
5679        return didSomething;
5680    }
5681
5682    private final boolean removeProcessLocked(ProcessRecord app,
5683            boolean callerWillRestart, boolean allowRestart, String reason) {
5684        final String name = app.processName;
5685        final int uid = app.uid;
5686        if (DEBUG_PROCESSES) Slog.d(
5687            TAG, "Force removing proc " + app.toShortString() + " (" + name
5688            + "/" + uid + ")");
5689
5690        mProcessNames.remove(name, uid);
5691        mIsolatedProcesses.remove(app.uid);
5692        if (mHeavyWeightProcess == app) {
5693            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5694                    mHeavyWeightProcess.userId, 0));
5695            mHeavyWeightProcess = null;
5696        }
5697        boolean needRestart = false;
5698        if (app.pid > 0 && app.pid != MY_PID) {
5699            int pid = app.pid;
5700            synchronized (mPidsSelfLocked) {
5701                mPidsSelfLocked.remove(pid);
5702                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5703            }
5704            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5705            if (app.isolated) {
5706                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5707            }
5708            app.kill(reason, true);
5709            handleAppDiedLocked(app, true, allowRestart);
5710            removeLruProcessLocked(app);
5711
5712            if (app.persistent && !app.isolated) {
5713                if (!callerWillRestart) {
5714                    addAppLocked(app.info, false, null /* ABI override */);
5715                } else {
5716                    needRestart = true;
5717                }
5718            }
5719        } else {
5720            mRemovedProcesses.add(app);
5721        }
5722
5723        return needRestart;
5724    }
5725
5726    private final void processStartTimedOutLocked(ProcessRecord app) {
5727        final int pid = app.pid;
5728        boolean gone = false;
5729        synchronized (mPidsSelfLocked) {
5730            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5731            if (knownApp != null && knownApp.thread == null) {
5732                mPidsSelfLocked.remove(pid);
5733                gone = true;
5734            }
5735        }
5736
5737        if (gone) {
5738            Slog.w(TAG, "Process " + app + " failed to attach");
5739            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5740                    pid, app.uid, app.processName);
5741            mProcessNames.remove(app.processName, app.uid);
5742            mIsolatedProcesses.remove(app.uid);
5743            if (mHeavyWeightProcess == app) {
5744                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5745                        mHeavyWeightProcess.userId, 0));
5746                mHeavyWeightProcess = null;
5747            }
5748            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5749            if (app.isolated) {
5750                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5751            }
5752            // Take care of any launching providers waiting for this process.
5753            checkAppInLaunchingProvidersLocked(app, true);
5754            // Take care of any services that are waiting for the process.
5755            mServices.processStartTimedOutLocked(app);
5756            app.kill("start timeout", true);
5757            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5758                Slog.w(TAG, "Unattached app died before backup, skipping");
5759                try {
5760                    IBackupManager bm = IBackupManager.Stub.asInterface(
5761                            ServiceManager.getService(Context.BACKUP_SERVICE));
5762                    bm.agentDisconnected(app.info.packageName);
5763                } catch (RemoteException e) {
5764                    // Can't happen; the backup manager is local
5765                }
5766            }
5767            if (isPendingBroadcastProcessLocked(pid)) {
5768                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5769                skipPendingBroadcastLocked(pid);
5770            }
5771        } else {
5772            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5773        }
5774    }
5775
5776    private final boolean attachApplicationLocked(IApplicationThread thread,
5777            int pid) {
5778
5779        // Find the application record that is being attached...  either via
5780        // the pid if we are running in multiple processes, or just pull the
5781        // next app record if we are emulating process with anonymous threads.
5782        ProcessRecord app;
5783        if (pid != MY_PID && pid >= 0) {
5784            synchronized (mPidsSelfLocked) {
5785                app = mPidsSelfLocked.get(pid);
5786            }
5787        } else {
5788            app = null;
5789        }
5790
5791        if (app == null) {
5792            Slog.w(TAG, "No pending application record for pid " + pid
5793                    + " (IApplicationThread " + thread + "); dropping process");
5794            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5795            if (pid > 0 && pid != MY_PID) {
5796                Process.killProcessQuiet(pid);
5797                //TODO: Process.killProcessGroup(app.info.uid, pid);
5798            } else {
5799                try {
5800                    thread.scheduleExit();
5801                } catch (Exception e) {
5802                    // Ignore exceptions.
5803                }
5804            }
5805            return false;
5806        }
5807
5808        // If this application record is still attached to a previous
5809        // process, clean it up now.
5810        if (app.thread != null) {
5811            handleAppDiedLocked(app, true, true);
5812        }
5813
5814        // Tell the process all about itself.
5815
5816        if (localLOGV) Slog.v(
5817                TAG, "Binding process pid " + pid + " to record " + app);
5818
5819        final String processName = app.processName;
5820        try {
5821            AppDeathRecipient adr = new AppDeathRecipient(
5822                    app, pid, thread);
5823            thread.asBinder().linkToDeath(adr, 0);
5824            app.deathRecipient = adr;
5825        } catch (RemoteException e) {
5826            app.resetPackageList(mProcessStats);
5827            startProcessLocked(app, "link fail", processName);
5828            return false;
5829        }
5830
5831        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5832
5833        app.makeActive(thread, mProcessStats);
5834        app.curAdj = app.setAdj = -100;
5835        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5836        app.forcingToForeground = null;
5837        updateProcessForegroundLocked(app, false, false);
5838        app.hasShownUi = false;
5839        app.debugging = false;
5840        app.cached = false;
5841
5842        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5843
5844        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5845        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5846
5847        if (!normalMode) {
5848            Slog.i(TAG, "Launching preboot mode app: " + app);
5849        }
5850
5851        if (localLOGV) Slog.v(
5852            TAG, "New app record " + app
5853            + " thread=" + thread.asBinder() + " pid=" + pid);
5854        try {
5855            int testMode = IApplicationThread.DEBUG_OFF;
5856            if (mDebugApp != null && mDebugApp.equals(processName)) {
5857                testMode = mWaitForDebugger
5858                    ? IApplicationThread.DEBUG_WAIT
5859                    : IApplicationThread.DEBUG_ON;
5860                app.debugging = true;
5861                if (mDebugTransient) {
5862                    mDebugApp = mOrigDebugApp;
5863                    mWaitForDebugger = mOrigWaitForDebugger;
5864                }
5865            }
5866            String profileFile = app.instrumentationProfileFile;
5867            ParcelFileDescriptor profileFd = null;
5868            int samplingInterval = 0;
5869            boolean profileAutoStop = false;
5870            if (mProfileApp != null && mProfileApp.equals(processName)) {
5871                mProfileProc = app;
5872                profileFile = mProfileFile;
5873                profileFd = mProfileFd;
5874                samplingInterval = mSamplingInterval;
5875                profileAutoStop = mAutoStopProfiler;
5876            }
5877            boolean enableOpenGlTrace = false;
5878            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5879                enableOpenGlTrace = true;
5880                mOpenGlTraceApp = null;
5881            }
5882
5883            // If the app is being launched for restore or full backup, set it up specially
5884            boolean isRestrictedBackupMode = false;
5885            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5886                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5887                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5888                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5889            }
5890
5891            ensurePackageDexOpt(app.instrumentationInfo != null
5892                    ? app.instrumentationInfo.packageName
5893                    : app.info.packageName);
5894            if (app.instrumentationClass != null) {
5895                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5896            }
5897            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5898                    + processName + " with config " + mConfiguration);
5899            ApplicationInfo appInfo = app.instrumentationInfo != null
5900                    ? app.instrumentationInfo : app.info;
5901            app.compat = compatibilityInfoForPackageLocked(appInfo);
5902            if (profileFd != null) {
5903                profileFd = profileFd.dup();
5904            }
5905            ProfilerInfo profilerInfo = profileFile == null ? null
5906                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5907            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5908                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5909                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5910                    isRestrictedBackupMode || !normalMode, app.persistent,
5911                    new Configuration(mConfiguration), app.compat,
5912                    getCommonServicesLocked(app.isolated),
5913                    mCoreSettingsObserver.getCoreSettingsLocked());
5914            updateLruProcessLocked(app, false, null);
5915            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5916        } catch (Exception e) {
5917            // todo: Yikes!  What should we do?  For now we will try to
5918            // start another process, but that could easily get us in
5919            // an infinite loop of restarting processes...
5920            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5921
5922            app.resetPackageList(mProcessStats);
5923            app.unlinkDeathRecipient();
5924            startProcessLocked(app, "bind fail", processName);
5925            return false;
5926        }
5927
5928        // Remove this record from the list of starting applications.
5929        mPersistentStartingProcesses.remove(app);
5930        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5931                "Attach application locked removing on hold: " + app);
5932        mProcessesOnHold.remove(app);
5933
5934        boolean badApp = false;
5935        boolean didSomething = false;
5936
5937        // See if the top visible activity is waiting to run in this process...
5938        if (normalMode) {
5939            try {
5940                if (mStackSupervisor.attachApplicationLocked(app)) {
5941                    didSomething = true;
5942                }
5943            } catch (Exception e) {
5944                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5945                badApp = true;
5946            }
5947        }
5948
5949        // Find any services that should be running in this process...
5950        if (!badApp) {
5951            try {
5952                didSomething |= mServices.attachApplicationLocked(app, processName);
5953            } catch (Exception e) {
5954                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5955                badApp = true;
5956            }
5957        }
5958
5959        // Check if a next-broadcast receiver is in this process...
5960        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5961            try {
5962                didSomething |= sendPendingBroadcastsLocked(app);
5963            } catch (Exception e) {
5964                // If the app died trying to launch the receiver we declare it 'bad'
5965                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
5966                badApp = true;
5967            }
5968        }
5969
5970        // Check whether the next backup agent is in this process...
5971        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5972            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5973            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5974            try {
5975                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5976                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5977                        mBackupTarget.backupMode);
5978            } catch (Exception e) {
5979                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
5980                badApp = true;
5981            }
5982        }
5983
5984        if (badApp) {
5985            app.kill("error during init", true);
5986            handleAppDiedLocked(app, false, true);
5987            return false;
5988        }
5989
5990        if (!didSomething) {
5991            updateOomAdjLocked();
5992        }
5993
5994        return true;
5995    }
5996
5997    @Override
5998    public final void attachApplication(IApplicationThread thread) {
5999        synchronized (this) {
6000            int callingPid = Binder.getCallingPid();
6001            final long origId = Binder.clearCallingIdentity();
6002            attachApplicationLocked(thread, callingPid);
6003            Binder.restoreCallingIdentity(origId);
6004        }
6005    }
6006
6007    @Override
6008    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6009        final long origId = Binder.clearCallingIdentity();
6010        synchronized (this) {
6011            ActivityStack stack = ActivityRecord.getStackLocked(token);
6012            if (stack != null) {
6013                ActivityRecord r =
6014                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6015                if (stopProfiling) {
6016                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6017                        try {
6018                            mProfileFd.close();
6019                        } catch (IOException e) {
6020                        }
6021                        clearProfilerLocked();
6022                    }
6023                }
6024            }
6025        }
6026        Binder.restoreCallingIdentity(origId);
6027    }
6028
6029    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6030        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6031                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6032    }
6033
6034    void enableScreenAfterBoot() {
6035        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6036                SystemClock.uptimeMillis());
6037        mWindowManager.enableScreenAfterBoot();
6038
6039        synchronized (this) {
6040            updateEventDispatchingLocked();
6041        }
6042    }
6043
6044    @Override
6045    public void showBootMessage(final CharSequence msg, final boolean always) {
6046        enforceNotIsolatedCaller("showBootMessage");
6047        mWindowManager.showBootMessage(msg, always);
6048    }
6049
6050    @Override
6051    public void keyguardWaitingForActivityDrawn() {
6052        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6053        final long token = Binder.clearCallingIdentity();
6054        try {
6055            synchronized (this) {
6056                if (DEBUG_LOCKSCREEN) logLockScreen("");
6057                mWindowManager.keyguardWaitingForActivityDrawn();
6058                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6059                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6060                }
6061            }
6062        } finally {
6063            Binder.restoreCallingIdentity(token);
6064        }
6065    }
6066
6067    final void finishBooting() {
6068        synchronized (this) {
6069            if (!mBootAnimationComplete) {
6070                mCallFinishBooting = true;
6071                return;
6072            }
6073            mCallFinishBooting = false;
6074        }
6075
6076        ArraySet<String> completedIsas = new ArraySet<String>();
6077        for (String abi : Build.SUPPORTED_ABIS) {
6078            Process.establishZygoteConnectionForAbi(abi);
6079            final String instructionSet = VMRuntime.getInstructionSet(abi);
6080            if (!completedIsas.contains(instructionSet)) {
6081                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6082                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6083                }
6084                completedIsas.add(instructionSet);
6085            }
6086        }
6087
6088        IntentFilter pkgFilter = new IntentFilter();
6089        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6090        pkgFilter.addDataScheme("package");
6091        mContext.registerReceiver(new BroadcastReceiver() {
6092            @Override
6093            public void onReceive(Context context, Intent intent) {
6094                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6095                if (pkgs != null) {
6096                    for (String pkg : pkgs) {
6097                        synchronized (ActivityManagerService.this) {
6098                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6099                                    0, "finished booting")) {
6100                                setResultCode(Activity.RESULT_OK);
6101                                return;
6102                            }
6103                        }
6104                    }
6105                }
6106            }
6107        }, pkgFilter);
6108
6109        // Let system services know.
6110        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6111
6112        synchronized (this) {
6113            // Ensure that any processes we had put on hold are now started
6114            // up.
6115            final int NP = mProcessesOnHold.size();
6116            if (NP > 0) {
6117                ArrayList<ProcessRecord> procs =
6118                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6119                for (int ip=0; ip<NP; ip++) {
6120                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6121                            + procs.get(ip));
6122                    startProcessLocked(procs.get(ip), "on-hold", null);
6123                }
6124            }
6125
6126            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6127                // Start looking for apps that are abusing wake locks.
6128                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6129                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6130                // Tell anyone interested that we are done booting!
6131                SystemProperties.set("sys.boot_completed", "1");
6132
6133                // And trigger dev.bootcomplete if we are not showing encryption progress
6134                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6135                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6136                    SystemProperties.set("dev.bootcomplete", "1");
6137                }
6138                for (int i=0; i<mStartedUsers.size(); i++) {
6139                    UserStartedState uss = mStartedUsers.valueAt(i);
6140                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6141                        uss.mState = UserStartedState.STATE_RUNNING;
6142                        final int userId = mStartedUsers.keyAt(i);
6143                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6144                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6145                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6146                        broadcastIntentLocked(null, null, intent, null,
6147                                new IIntentReceiver.Stub() {
6148                                    @Override
6149                                    public void performReceive(Intent intent, int resultCode,
6150                                            String data, Bundle extras, boolean ordered,
6151                                            boolean sticky, int sendingUser) {
6152                                        synchronized (ActivityManagerService.this) {
6153                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6154                                                    true, false);
6155                                        }
6156                                    }
6157                                },
6158                                0, null, null,
6159                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6160                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6161                                userId);
6162                    }
6163                }
6164                scheduleStartProfilesLocked();
6165            }
6166        }
6167    }
6168
6169    @Override
6170    public void bootAnimationComplete() {
6171        final boolean callFinishBooting;
6172        synchronized (this) {
6173            callFinishBooting = mCallFinishBooting;
6174            mBootAnimationComplete = true;
6175        }
6176        if (callFinishBooting) {
6177            finishBooting();
6178        }
6179    }
6180
6181    final void ensureBootCompleted() {
6182        boolean booting;
6183        boolean enableScreen;
6184        synchronized (this) {
6185            booting = mBooting;
6186            mBooting = false;
6187            enableScreen = !mBooted;
6188            mBooted = true;
6189        }
6190
6191        if (booting) {
6192            finishBooting();
6193        }
6194
6195        if (enableScreen) {
6196            enableScreenAfterBoot();
6197        }
6198    }
6199
6200    @Override
6201    public final void activityResumed(IBinder token) {
6202        final long origId = Binder.clearCallingIdentity();
6203        synchronized(this) {
6204            ActivityStack stack = ActivityRecord.getStackLocked(token);
6205            if (stack != null) {
6206                ActivityRecord.activityResumedLocked(token);
6207            }
6208        }
6209        Binder.restoreCallingIdentity(origId);
6210    }
6211
6212    @Override
6213    public final void activityPaused(IBinder token) {
6214        final long origId = Binder.clearCallingIdentity();
6215        synchronized(this) {
6216            ActivityStack stack = ActivityRecord.getStackLocked(token);
6217            if (stack != null) {
6218                stack.activityPausedLocked(token, false);
6219            }
6220        }
6221        Binder.restoreCallingIdentity(origId);
6222    }
6223
6224    @Override
6225    public final void activityStopped(IBinder token, Bundle icicle,
6226            PersistableBundle persistentState, CharSequence description) {
6227        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6228
6229        // Refuse possible leaked file descriptors
6230        if (icicle != null && icicle.hasFileDescriptors()) {
6231            throw new IllegalArgumentException("File descriptors passed in Bundle");
6232        }
6233
6234        final long origId = Binder.clearCallingIdentity();
6235
6236        synchronized (this) {
6237            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6238            if (r != null) {
6239                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6240            }
6241        }
6242
6243        trimApplications();
6244
6245        Binder.restoreCallingIdentity(origId);
6246    }
6247
6248    @Override
6249    public final void activityDestroyed(IBinder token) {
6250        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6251        synchronized (this) {
6252            ActivityStack stack = ActivityRecord.getStackLocked(token);
6253            if (stack != null) {
6254                stack.activityDestroyedLocked(token);
6255            }
6256        }
6257    }
6258
6259    @Override
6260    public final void backgroundResourcesReleased(IBinder token) {
6261        final long origId = Binder.clearCallingIdentity();
6262        try {
6263            synchronized (this) {
6264                ActivityStack stack = ActivityRecord.getStackLocked(token);
6265                if (stack != null) {
6266                    stack.backgroundResourcesReleased(token);
6267                }
6268            }
6269        } finally {
6270            Binder.restoreCallingIdentity(origId);
6271        }
6272    }
6273
6274    @Override
6275    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6276        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6277    }
6278
6279    @Override
6280    public final void notifyEnterAnimationComplete(IBinder token) {
6281        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6282    }
6283
6284    @Override
6285    public String getCallingPackage(IBinder token) {
6286        synchronized (this) {
6287            ActivityRecord r = getCallingRecordLocked(token);
6288            return r != null ? r.info.packageName : null;
6289        }
6290    }
6291
6292    @Override
6293    public ComponentName getCallingActivity(IBinder token) {
6294        synchronized (this) {
6295            ActivityRecord r = getCallingRecordLocked(token);
6296            return r != null ? r.intent.getComponent() : null;
6297        }
6298    }
6299
6300    private ActivityRecord getCallingRecordLocked(IBinder token) {
6301        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6302        if (r == null) {
6303            return null;
6304        }
6305        return r.resultTo;
6306    }
6307
6308    @Override
6309    public ComponentName getActivityClassForToken(IBinder token) {
6310        synchronized(this) {
6311            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6312            if (r == null) {
6313                return null;
6314            }
6315            return r.intent.getComponent();
6316        }
6317    }
6318
6319    @Override
6320    public String getPackageForToken(IBinder token) {
6321        synchronized(this) {
6322            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6323            if (r == null) {
6324                return null;
6325            }
6326            return r.packageName;
6327        }
6328    }
6329
6330    @Override
6331    public IIntentSender getIntentSender(int type,
6332            String packageName, IBinder token, String resultWho,
6333            int requestCode, Intent[] intents, String[] resolvedTypes,
6334            int flags, Bundle options, int userId) {
6335        enforceNotIsolatedCaller("getIntentSender");
6336        // Refuse possible leaked file descriptors
6337        if (intents != null) {
6338            if (intents.length < 1) {
6339                throw new IllegalArgumentException("Intents array length must be >= 1");
6340            }
6341            for (int i=0; i<intents.length; i++) {
6342                Intent intent = intents[i];
6343                if (intent != null) {
6344                    if (intent.hasFileDescriptors()) {
6345                        throw new IllegalArgumentException("File descriptors passed in Intent");
6346                    }
6347                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6348                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6349                        throw new IllegalArgumentException(
6350                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6351                    }
6352                    intents[i] = new Intent(intent);
6353                }
6354            }
6355            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6356                throw new IllegalArgumentException(
6357                        "Intent array length does not match resolvedTypes length");
6358            }
6359        }
6360        if (options != null) {
6361            if (options.hasFileDescriptors()) {
6362                throw new IllegalArgumentException("File descriptors passed in options");
6363            }
6364        }
6365
6366        synchronized(this) {
6367            int callingUid = Binder.getCallingUid();
6368            int origUserId = userId;
6369            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6370                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6371                    ALLOW_NON_FULL, "getIntentSender", null);
6372            if (origUserId == UserHandle.USER_CURRENT) {
6373                // We don't want to evaluate this until the pending intent is
6374                // actually executed.  However, we do want to always do the
6375                // security checking for it above.
6376                userId = UserHandle.USER_CURRENT;
6377            }
6378            try {
6379                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6380                    int uid = AppGlobals.getPackageManager()
6381                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6382                    if (!UserHandle.isSameApp(callingUid, uid)) {
6383                        String msg = "Permission Denial: getIntentSender() from pid="
6384                            + Binder.getCallingPid()
6385                            + ", uid=" + Binder.getCallingUid()
6386                            + ", (need uid=" + uid + ")"
6387                            + " is not allowed to send as package " + packageName;
6388                        Slog.w(TAG, msg);
6389                        throw new SecurityException(msg);
6390                    }
6391                }
6392
6393                return getIntentSenderLocked(type, packageName, callingUid, userId,
6394                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6395
6396            } catch (RemoteException e) {
6397                throw new SecurityException(e);
6398            }
6399        }
6400    }
6401
6402    IIntentSender getIntentSenderLocked(int type, String packageName,
6403            int callingUid, int userId, IBinder token, String resultWho,
6404            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6405            Bundle options) {
6406        if (DEBUG_MU)
6407            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6408        ActivityRecord activity = null;
6409        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6410            activity = ActivityRecord.isInStackLocked(token);
6411            if (activity == null) {
6412                return null;
6413            }
6414            if (activity.finishing) {
6415                return null;
6416            }
6417        }
6418
6419        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6420        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6421        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6422        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6423                |PendingIntent.FLAG_UPDATE_CURRENT);
6424
6425        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6426                type, packageName, activity, resultWho,
6427                requestCode, intents, resolvedTypes, flags, options, userId);
6428        WeakReference<PendingIntentRecord> ref;
6429        ref = mIntentSenderRecords.get(key);
6430        PendingIntentRecord rec = ref != null ? ref.get() : null;
6431        if (rec != null) {
6432            if (!cancelCurrent) {
6433                if (updateCurrent) {
6434                    if (rec.key.requestIntent != null) {
6435                        rec.key.requestIntent.replaceExtras(intents != null ?
6436                                intents[intents.length - 1] : null);
6437                    }
6438                    if (intents != null) {
6439                        intents[intents.length-1] = rec.key.requestIntent;
6440                        rec.key.allIntents = intents;
6441                        rec.key.allResolvedTypes = resolvedTypes;
6442                    } else {
6443                        rec.key.allIntents = null;
6444                        rec.key.allResolvedTypes = null;
6445                    }
6446                }
6447                return rec;
6448            }
6449            rec.canceled = true;
6450            mIntentSenderRecords.remove(key);
6451        }
6452        if (noCreate) {
6453            return rec;
6454        }
6455        rec = new PendingIntentRecord(this, key, callingUid);
6456        mIntentSenderRecords.put(key, rec.ref);
6457        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6458            if (activity.pendingResults == null) {
6459                activity.pendingResults
6460                        = new HashSet<WeakReference<PendingIntentRecord>>();
6461            }
6462            activity.pendingResults.add(rec.ref);
6463        }
6464        return rec;
6465    }
6466
6467    @Override
6468    public void cancelIntentSender(IIntentSender sender) {
6469        if (!(sender instanceof PendingIntentRecord)) {
6470            return;
6471        }
6472        synchronized(this) {
6473            PendingIntentRecord rec = (PendingIntentRecord)sender;
6474            try {
6475                int uid = AppGlobals.getPackageManager()
6476                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6477                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6478                    String msg = "Permission Denial: cancelIntentSender() from pid="
6479                        + Binder.getCallingPid()
6480                        + ", uid=" + Binder.getCallingUid()
6481                        + " is not allowed to cancel packges "
6482                        + rec.key.packageName;
6483                    Slog.w(TAG, msg);
6484                    throw new SecurityException(msg);
6485                }
6486            } catch (RemoteException e) {
6487                throw new SecurityException(e);
6488            }
6489            cancelIntentSenderLocked(rec, true);
6490        }
6491    }
6492
6493    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6494        rec.canceled = true;
6495        mIntentSenderRecords.remove(rec.key);
6496        if (cleanActivity && rec.key.activity != null) {
6497            rec.key.activity.pendingResults.remove(rec.ref);
6498        }
6499    }
6500
6501    @Override
6502    public String getPackageForIntentSender(IIntentSender pendingResult) {
6503        if (!(pendingResult instanceof PendingIntentRecord)) {
6504            return null;
6505        }
6506        try {
6507            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6508            return res.key.packageName;
6509        } catch (ClassCastException e) {
6510        }
6511        return null;
6512    }
6513
6514    @Override
6515    public int getUidForIntentSender(IIntentSender sender) {
6516        if (sender instanceof PendingIntentRecord) {
6517            try {
6518                PendingIntentRecord res = (PendingIntentRecord)sender;
6519                return res.uid;
6520            } catch (ClassCastException e) {
6521            }
6522        }
6523        return -1;
6524    }
6525
6526    @Override
6527    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6528        if (!(pendingResult instanceof PendingIntentRecord)) {
6529            return false;
6530        }
6531        try {
6532            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6533            if (res.key.allIntents == null) {
6534                return false;
6535            }
6536            for (int i=0; i<res.key.allIntents.length; i++) {
6537                Intent intent = res.key.allIntents[i];
6538                if (intent.getPackage() != null && intent.getComponent() != null) {
6539                    return false;
6540                }
6541            }
6542            return true;
6543        } catch (ClassCastException e) {
6544        }
6545        return false;
6546    }
6547
6548    @Override
6549    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6550        if (!(pendingResult instanceof PendingIntentRecord)) {
6551            return false;
6552        }
6553        try {
6554            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6555            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6556                return true;
6557            }
6558            return false;
6559        } catch (ClassCastException e) {
6560        }
6561        return false;
6562    }
6563
6564    @Override
6565    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6566        if (!(pendingResult instanceof PendingIntentRecord)) {
6567            return null;
6568        }
6569        try {
6570            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6571            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6572        } catch (ClassCastException e) {
6573        }
6574        return null;
6575    }
6576
6577    @Override
6578    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6579        if (!(pendingResult instanceof PendingIntentRecord)) {
6580            return null;
6581        }
6582        try {
6583            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6584            Intent intent = res.key.requestIntent;
6585            if (intent != null) {
6586                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6587                        || res.lastTagPrefix.equals(prefix))) {
6588                    return res.lastTag;
6589                }
6590                res.lastTagPrefix = prefix;
6591                StringBuilder sb = new StringBuilder(128);
6592                if (prefix != null) {
6593                    sb.append(prefix);
6594                }
6595                if (intent.getAction() != null) {
6596                    sb.append(intent.getAction());
6597                } else if (intent.getComponent() != null) {
6598                    intent.getComponent().appendShortString(sb);
6599                } else {
6600                    sb.append("?");
6601                }
6602                return res.lastTag = sb.toString();
6603            }
6604        } catch (ClassCastException e) {
6605        }
6606        return null;
6607    }
6608
6609    @Override
6610    public void setProcessLimit(int max) {
6611        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6612                "setProcessLimit()");
6613        synchronized (this) {
6614            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6615            mProcessLimitOverride = max;
6616        }
6617        trimApplications();
6618    }
6619
6620    @Override
6621    public int getProcessLimit() {
6622        synchronized (this) {
6623            return mProcessLimitOverride;
6624        }
6625    }
6626
6627    void foregroundTokenDied(ForegroundToken token) {
6628        synchronized (ActivityManagerService.this) {
6629            synchronized (mPidsSelfLocked) {
6630                ForegroundToken cur
6631                    = mForegroundProcesses.get(token.pid);
6632                if (cur != token) {
6633                    return;
6634                }
6635                mForegroundProcesses.remove(token.pid);
6636                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6637                if (pr == null) {
6638                    return;
6639                }
6640                pr.forcingToForeground = null;
6641                updateProcessForegroundLocked(pr, false, false);
6642            }
6643            updateOomAdjLocked();
6644        }
6645    }
6646
6647    @Override
6648    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6649        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6650                "setProcessForeground()");
6651        synchronized(this) {
6652            boolean changed = false;
6653
6654            synchronized (mPidsSelfLocked) {
6655                ProcessRecord pr = mPidsSelfLocked.get(pid);
6656                if (pr == null && isForeground) {
6657                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6658                    return;
6659                }
6660                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6661                if (oldToken != null) {
6662                    oldToken.token.unlinkToDeath(oldToken, 0);
6663                    mForegroundProcesses.remove(pid);
6664                    if (pr != null) {
6665                        pr.forcingToForeground = null;
6666                    }
6667                    changed = true;
6668                }
6669                if (isForeground && token != null) {
6670                    ForegroundToken newToken = new ForegroundToken() {
6671                        @Override
6672                        public void binderDied() {
6673                            foregroundTokenDied(this);
6674                        }
6675                    };
6676                    newToken.pid = pid;
6677                    newToken.token = token;
6678                    try {
6679                        token.linkToDeath(newToken, 0);
6680                        mForegroundProcesses.put(pid, newToken);
6681                        pr.forcingToForeground = token;
6682                        changed = true;
6683                    } catch (RemoteException e) {
6684                        // If the process died while doing this, we will later
6685                        // do the cleanup with the process death link.
6686                    }
6687                }
6688            }
6689
6690            if (changed) {
6691                updateOomAdjLocked();
6692            }
6693        }
6694    }
6695
6696    // =========================================================
6697    // PERMISSIONS
6698    // =========================================================
6699
6700    static class PermissionController extends IPermissionController.Stub {
6701        ActivityManagerService mActivityManagerService;
6702        PermissionController(ActivityManagerService activityManagerService) {
6703            mActivityManagerService = activityManagerService;
6704        }
6705
6706        @Override
6707        public boolean checkPermission(String permission, int pid, int uid) {
6708            return mActivityManagerService.checkPermission(permission, pid,
6709                    uid) == PackageManager.PERMISSION_GRANTED;
6710        }
6711    }
6712
6713    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6714        @Override
6715        public int checkComponentPermission(String permission, int pid, int uid,
6716                int owningUid, boolean exported) {
6717            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6718                    owningUid, exported);
6719        }
6720
6721        @Override
6722        public Object getAMSLock() {
6723            return ActivityManagerService.this;
6724        }
6725    }
6726
6727    /**
6728     * This can be called with or without the global lock held.
6729     */
6730    int checkComponentPermission(String permission, int pid, int uid,
6731            int owningUid, boolean exported) {
6732        if (pid == MY_PID) {
6733            return PackageManager.PERMISSION_GRANTED;
6734        }
6735        return ActivityManager.checkComponentPermission(permission, uid,
6736                owningUid, exported);
6737    }
6738
6739    /**
6740     * As the only public entry point for permissions checking, this method
6741     * can enforce the semantic that requesting a check on a null global
6742     * permission is automatically denied.  (Internally a null permission
6743     * string is used when calling {@link #checkComponentPermission} in cases
6744     * when only uid-based security is needed.)
6745     *
6746     * This can be called with or without the global lock held.
6747     */
6748    @Override
6749    public int checkPermission(String permission, int pid, int uid) {
6750        if (permission == null) {
6751            return PackageManager.PERMISSION_DENIED;
6752        }
6753        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6754    }
6755
6756    @Override
6757    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6758        if (permission == null) {
6759            return PackageManager.PERMISSION_DENIED;
6760        }
6761
6762        // We might be performing an operation on behalf of an indirect binder
6763        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6764        // client identity accordingly before proceeding.
6765        Identity tlsIdentity = sCallerIdentity.get();
6766        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6767            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6768                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6769            uid = tlsIdentity.uid;
6770            pid = tlsIdentity.pid;
6771        }
6772
6773        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6774    }
6775
6776    /**
6777     * Binder IPC calls go through the public entry point.
6778     * This can be called with or without the global lock held.
6779     */
6780    int checkCallingPermission(String permission) {
6781        return checkPermission(permission,
6782                Binder.getCallingPid(),
6783                UserHandle.getAppId(Binder.getCallingUid()));
6784    }
6785
6786    /**
6787     * This can be called with or without the global lock held.
6788     */
6789    void enforceCallingPermission(String permission, String func) {
6790        if (checkCallingPermission(permission)
6791                == PackageManager.PERMISSION_GRANTED) {
6792            return;
6793        }
6794
6795        String msg = "Permission Denial: " + func + " from pid="
6796                + Binder.getCallingPid()
6797                + ", uid=" + Binder.getCallingUid()
6798                + " requires " + permission;
6799        Slog.w(TAG, msg);
6800        throw new SecurityException(msg);
6801    }
6802
6803    /**
6804     * Determine if UID is holding permissions required to access {@link Uri} in
6805     * the given {@link ProviderInfo}. Final permission checking is always done
6806     * in {@link ContentProvider}.
6807     */
6808    private final boolean checkHoldingPermissionsLocked(
6809            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6810        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6811                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6812        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6813            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6814                    != PERMISSION_GRANTED) {
6815                return false;
6816            }
6817        }
6818        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6819    }
6820
6821    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6822            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6823        if (pi.applicationInfo.uid == uid) {
6824            return true;
6825        } else if (!pi.exported) {
6826            return false;
6827        }
6828
6829        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6830        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6831        try {
6832            // check if target holds top-level <provider> permissions
6833            if (!readMet && pi.readPermission != null && considerUidPermissions
6834                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6835                readMet = true;
6836            }
6837            if (!writeMet && pi.writePermission != null && considerUidPermissions
6838                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6839                writeMet = true;
6840            }
6841
6842            // track if unprotected read/write is allowed; any denied
6843            // <path-permission> below removes this ability
6844            boolean allowDefaultRead = pi.readPermission == null;
6845            boolean allowDefaultWrite = pi.writePermission == null;
6846
6847            // check if target holds any <path-permission> that match uri
6848            final PathPermission[] pps = pi.pathPermissions;
6849            if (pps != null) {
6850                final String path = grantUri.uri.getPath();
6851                int i = pps.length;
6852                while (i > 0 && (!readMet || !writeMet)) {
6853                    i--;
6854                    PathPermission pp = pps[i];
6855                    if (pp.match(path)) {
6856                        if (!readMet) {
6857                            final String pprperm = pp.getReadPermission();
6858                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6859                                    + pprperm + " for " + pp.getPath()
6860                                    + ": match=" + pp.match(path)
6861                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6862                            if (pprperm != null) {
6863                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6864                                        == PERMISSION_GRANTED) {
6865                                    readMet = true;
6866                                } else {
6867                                    allowDefaultRead = false;
6868                                }
6869                            }
6870                        }
6871                        if (!writeMet) {
6872                            final String ppwperm = pp.getWritePermission();
6873                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6874                                    + ppwperm + " for " + pp.getPath()
6875                                    + ": match=" + pp.match(path)
6876                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6877                            if (ppwperm != null) {
6878                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6879                                        == PERMISSION_GRANTED) {
6880                                    writeMet = true;
6881                                } else {
6882                                    allowDefaultWrite = false;
6883                                }
6884                            }
6885                        }
6886                    }
6887                }
6888            }
6889
6890            // grant unprotected <provider> read/write, if not blocked by
6891            // <path-permission> above
6892            if (allowDefaultRead) readMet = true;
6893            if (allowDefaultWrite) writeMet = true;
6894
6895        } catch (RemoteException e) {
6896            return false;
6897        }
6898
6899        return readMet && writeMet;
6900    }
6901
6902    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6903        ProviderInfo pi = null;
6904        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6905        if (cpr != null) {
6906            pi = cpr.info;
6907        } else {
6908            try {
6909                pi = AppGlobals.getPackageManager().resolveContentProvider(
6910                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6911            } catch (RemoteException ex) {
6912            }
6913        }
6914        return pi;
6915    }
6916
6917    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6918        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6919        if (targetUris != null) {
6920            return targetUris.get(grantUri);
6921        }
6922        return null;
6923    }
6924
6925    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6926            String targetPkg, int targetUid, GrantUri grantUri) {
6927        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6928        if (targetUris == null) {
6929            targetUris = Maps.newArrayMap();
6930            mGrantedUriPermissions.put(targetUid, targetUris);
6931        }
6932
6933        UriPermission perm = targetUris.get(grantUri);
6934        if (perm == null) {
6935            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6936            targetUris.put(grantUri, perm);
6937        }
6938
6939        return perm;
6940    }
6941
6942    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6943            final int modeFlags) {
6944        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6945        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6946                : UriPermission.STRENGTH_OWNED;
6947
6948        // Root gets to do everything.
6949        if (uid == 0) {
6950            return true;
6951        }
6952
6953        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6954        if (perms == null) return false;
6955
6956        // First look for exact match
6957        final UriPermission exactPerm = perms.get(grantUri);
6958        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6959            return true;
6960        }
6961
6962        // No exact match, look for prefixes
6963        final int N = perms.size();
6964        for (int i = 0; i < N; i++) {
6965            final UriPermission perm = perms.valueAt(i);
6966            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6967                    && perm.getStrength(modeFlags) >= minStrength) {
6968                return true;
6969            }
6970        }
6971
6972        return false;
6973    }
6974
6975    /**
6976     * @param uri This uri must NOT contain an embedded userId.
6977     * @param userId The userId in which the uri is to be resolved.
6978     */
6979    @Override
6980    public int checkUriPermission(Uri uri, int pid, int uid,
6981            final int modeFlags, int userId, IBinder callerToken) {
6982        enforceNotIsolatedCaller("checkUriPermission");
6983
6984        // Another redirected-binder-call permissions check as in
6985        // {@link checkPermissionWithToken}.
6986        Identity tlsIdentity = sCallerIdentity.get();
6987        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6988            uid = tlsIdentity.uid;
6989            pid = tlsIdentity.pid;
6990        }
6991
6992        // Our own process gets to do everything.
6993        if (pid == MY_PID) {
6994            return PackageManager.PERMISSION_GRANTED;
6995        }
6996        synchronized (this) {
6997            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6998                    ? PackageManager.PERMISSION_GRANTED
6999                    : PackageManager.PERMISSION_DENIED;
7000        }
7001    }
7002
7003    /**
7004     * Check if the targetPkg can be granted permission to access uri by
7005     * the callingUid using the given modeFlags.  Throws a security exception
7006     * if callingUid is not allowed to do this.  Returns the uid of the target
7007     * if the URI permission grant should be performed; returns -1 if it is not
7008     * needed (for example targetPkg already has permission to access the URI).
7009     * If you already know the uid of the target, you can supply it in
7010     * lastTargetUid else set that to -1.
7011     */
7012    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7013            final int modeFlags, int lastTargetUid) {
7014        if (!Intent.isAccessUriMode(modeFlags)) {
7015            return -1;
7016        }
7017
7018        if (targetPkg != null) {
7019            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7020                    "Checking grant " + targetPkg + " permission to " + grantUri);
7021        }
7022
7023        final IPackageManager pm = AppGlobals.getPackageManager();
7024
7025        // If this is not a content: uri, we can't do anything with it.
7026        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7027            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7028                    "Can't grant URI permission for non-content URI: " + grantUri);
7029            return -1;
7030        }
7031
7032        final String authority = grantUri.uri.getAuthority();
7033        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7034        if (pi == null) {
7035            Slog.w(TAG, "No content provider found for permission check: " +
7036                    grantUri.uri.toSafeString());
7037            return -1;
7038        }
7039
7040        int targetUid = lastTargetUid;
7041        if (targetUid < 0 && targetPkg != null) {
7042            try {
7043                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7044                if (targetUid < 0) {
7045                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7046                            "Can't grant URI permission no uid for: " + targetPkg);
7047                    return -1;
7048                }
7049            } catch (RemoteException ex) {
7050                return -1;
7051            }
7052        }
7053
7054        if (targetUid >= 0) {
7055            // First...  does the target actually need this permission?
7056            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7057                // No need to grant the target this permission.
7058                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7059                        "Target " + targetPkg + " already has full permission to " + grantUri);
7060                return -1;
7061            }
7062        } else {
7063            // First...  there is no target package, so can anyone access it?
7064            boolean allowed = pi.exported;
7065            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7066                if (pi.readPermission != null) {
7067                    allowed = false;
7068                }
7069            }
7070            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7071                if (pi.writePermission != null) {
7072                    allowed = false;
7073                }
7074            }
7075            if (allowed) {
7076                return -1;
7077            }
7078        }
7079
7080        /* There is a special cross user grant if:
7081         * - The target is on another user.
7082         * - Apps on the current user can access the uri without any uid permissions.
7083         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7084         * grant uri permissions.
7085         */
7086        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7087                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7088                modeFlags, false /*without considering the uid permissions*/);
7089
7090        // Second...  is the provider allowing granting of URI permissions?
7091        if (!specialCrossUserGrant) {
7092            if (!pi.grantUriPermissions) {
7093                throw new SecurityException("Provider " + pi.packageName
7094                        + "/" + pi.name
7095                        + " does not allow granting of Uri permissions (uri "
7096                        + grantUri + ")");
7097            }
7098            if (pi.uriPermissionPatterns != null) {
7099                final int N = pi.uriPermissionPatterns.length;
7100                boolean allowed = false;
7101                for (int i=0; i<N; i++) {
7102                    if (pi.uriPermissionPatterns[i] != null
7103                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7104                        allowed = true;
7105                        break;
7106                    }
7107                }
7108                if (!allowed) {
7109                    throw new SecurityException("Provider " + pi.packageName
7110                            + "/" + pi.name
7111                            + " does not allow granting of permission to path of Uri "
7112                            + grantUri);
7113                }
7114            }
7115        }
7116
7117        // Third...  does the caller itself have permission to access
7118        // this uri?
7119        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7120            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7121                // Require they hold a strong enough Uri permission
7122                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7123                    throw new SecurityException("Uid " + callingUid
7124                            + " does not have permission to uri " + grantUri);
7125                }
7126            }
7127        }
7128        return targetUid;
7129    }
7130
7131    /**
7132     * @param uri This uri must NOT contain an embedded userId.
7133     * @param userId The userId in which the uri is to be resolved.
7134     */
7135    @Override
7136    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7137            final int modeFlags, int userId) {
7138        enforceNotIsolatedCaller("checkGrantUriPermission");
7139        synchronized(this) {
7140            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7141                    new GrantUri(userId, uri, false), modeFlags, -1);
7142        }
7143    }
7144
7145    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7146            final int modeFlags, UriPermissionOwner owner) {
7147        if (!Intent.isAccessUriMode(modeFlags)) {
7148            return;
7149        }
7150
7151        // So here we are: the caller has the assumed permission
7152        // to the uri, and the target doesn't.  Let's now give this to
7153        // the target.
7154
7155        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7156                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7157
7158        final String authority = grantUri.uri.getAuthority();
7159        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7160        if (pi == null) {
7161            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7162            return;
7163        }
7164
7165        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7166            grantUri.prefix = true;
7167        }
7168        final UriPermission perm = findOrCreateUriPermissionLocked(
7169                pi.packageName, targetPkg, targetUid, grantUri);
7170        perm.grantModes(modeFlags, owner);
7171    }
7172
7173    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7174            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7175        if (targetPkg == null) {
7176            throw new NullPointerException("targetPkg");
7177        }
7178        int targetUid;
7179        final IPackageManager pm = AppGlobals.getPackageManager();
7180        try {
7181            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7182        } catch (RemoteException ex) {
7183            return;
7184        }
7185
7186        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7187                targetUid);
7188        if (targetUid < 0) {
7189            return;
7190        }
7191
7192        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7193                owner);
7194    }
7195
7196    static class NeededUriGrants extends ArrayList<GrantUri> {
7197        final String targetPkg;
7198        final int targetUid;
7199        final int flags;
7200
7201        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7202            this.targetPkg = targetPkg;
7203            this.targetUid = targetUid;
7204            this.flags = flags;
7205        }
7206    }
7207
7208    /**
7209     * Like checkGrantUriPermissionLocked, but takes an Intent.
7210     */
7211    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7212            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7213        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7214                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7215                + " clip=" + (intent != null ? intent.getClipData() : null)
7216                + " from " + intent + "; flags=0x"
7217                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7218
7219        if (targetPkg == null) {
7220            throw new NullPointerException("targetPkg");
7221        }
7222
7223        if (intent == null) {
7224            return null;
7225        }
7226        Uri data = intent.getData();
7227        ClipData clip = intent.getClipData();
7228        if (data == null && clip == null) {
7229            return null;
7230        }
7231        // Default userId for uris in the intent (if they don't specify it themselves)
7232        int contentUserHint = intent.getContentUserHint();
7233        if (contentUserHint == UserHandle.USER_CURRENT) {
7234            contentUserHint = UserHandle.getUserId(callingUid);
7235        }
7236        final IPackageManager pm = AppGlobals.getPackageManager();
7237        int targetUid;
7238        if (needed != null) {
7239            targetUid = needed.targetUid;
7240        } else {
7241            try {
7242                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7243            } catch (RemoteException ex) {
7244                return null;
7245            }
7246            if (targetUid < 0) {
7247                if (DEBUG_URI_PERMISSION) {
7248                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7249                            + " on user " + targetUserId);
7250                }
7251                return null;
7252            }
7253        }
7254        if (data != null) {
7255            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7256            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7257                    targetUid);
7258            if (targetUid > 0) {
7259                if (needed == null) {
7260                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7261                }
7262                needed.add(grantUri);
7263            }
7264        }
7265        if (clip != null) {
7266            for (int i=0; i<clip.getItemCount(); i++) {
7267                Uri uri = clip.getItemAt(i).getUri();
7268                if (uri != null) {
7269                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7270                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7271                            targetUid);
7272                    if (targetUid > 0) {
7273                        if (needed == null) {
7274                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7275                        }
7276                        needed.add(grantUri);
7277                    }
7278                } else {
7279                    Intent clipIntent = clip.getItemAt(i).getIntent();
7280                    if (clipIntent != null) {
7281                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7282                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7283                        if (newNeeded != null) {
7284                            needed = newNeeded;
7285                        }
7286                    }
7287                }
7288            }
7289        }
7290
7291        return needed;
7292    }
7293
7294    /**
7295     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7296     */
7297    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7298            UriPermissionOwner owner) {
7299        if (needed != null) {
7300            for (int i=0; i<needed.size(); i++) {
7301                GrantUri grantUri = needed.get(i);
7302                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7303                        grantUri, needed.flags, owner);
7304            }
7305        }
7306    }
7307
7308    void grantUriPermissionFromIntentLocked(int callingUid,
7309            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7310        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7311                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7312        if (needed == null) {
7313            return;
7314        }
7315
7316        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7317    }
7318
7319    /**
7320     * @param uri This uri must NOT contain an embedded userId.
7321     * @param userId The userId in which the uri is to be resolved.
7322     */
7323    @Override
7324    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7325            final int modeFlags, int userId) {
7326        enforceNotIsolatedCaller("grantUriPermission");
7327        GrantUri grantUri = new GrantUri(userId, uri, false);
7328        synchronized(this) {
7329            final ProcessRecord r = getRecordForAppLocked(caller);
7330            if (r == null) {
7331                throw new SecurityException("Unable to find app for caller "
7332                        + caller
7333                        + " when granting permission to uri " + grantUri);
7334            }
7335            if (targetPkg == null) {
7336                throw new IllegalArgumentException("null target");
7337            }
7338            if (grantUri == null) {
7339                throw new IllegalArgumentException("null uri");
7340            }
7341
7342            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7343                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7344                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7345                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7346
7347            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7348                    UserHandle.getUserId(r.uid));
7349        }
7350    }
7351
7352    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7353        if (perm.modeFlags == 0) {
7354            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7355                    perm.targetUid);
7356            if (perms != null) {
7357                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7358                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7359
7360                perms.remove(perm.uri);
7361                if (perms.isEmpty()) {
7362                    mGrantedUriPermissions.remove(perm.targetUid);
7363                }
7364            }
7365        }
7366    }
7367
7368    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7369        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7370
7371        final IPackageManager pm = AppGlobals.getPackageManager();
7372        final String authority = grantUri.uri.getAuthority();
7373        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7374        if (pi == null) {
7375            Slog.w(TAG, "No content provider found for permission revoke: "
7376                    + grantUri.toSafeString());
7377            return;
7378        }
7379
7380        // Does the caller have this permission on the URI?
7381        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7382            // If they don't have direct access to the URI, then revoke any
7383            // ownerless URI permissions that have been granted to them.
7384            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7385            if (perms != null) {
7386                boolean persistChanged = false;
7387                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7388                    final UriPermission perm = it.next();
7389                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7390                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7391                        if (DEBUG_URI_PERMISSION)
7392                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7393                                    " permission to " + perm.uri);
7394                        persistChanged |= perm.revokeModes(
7395                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7396                        if (perm.modeFlags == 0) {
7397                            it.remove();
7398                        }
7399                    }
7400                }
7401                if (perms.isEmpty()) {
7402                    mGrantedUriPermissions.remove(callingUid);
7403                }
7404                if (persistChanged) {
7405                    schedulePersistUriGrants();
7406                }
7407            }
7408            return;
7409        }
7410
7411        boolean persistChanged = false;
7412
7413        // Go through all of the permissions and remove any that match.
7414        int N = mGrantedUriPermissions.size();
7415        for (int i = 0; i < N; i++) {
7416            final int targetUid = mGrantedUriPermissions.keyAt(i);
7417            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7418
7419            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7420                final UriPermission perm = it.next();
7421                if (perm.uri.sourceUserId == grantUri.sourceUserId
7422                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7423                    if (DEBUG_URI_PERMISSION)
7424                        Slog.v(TAG,
7425                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7426                    persistChanged |= perm.revokeModes(
7427                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7428                    if (perm.modeFlags == 0) {
7429                        it.remove();
7430                    }
7431                }
7432            }
7433
7434            if (perms.isEmpty()) {
7435                mGrantedUriPermissions.remove(targetUid);
7436                N--;
7437                i--;
7438            }
7439        }
7440
7441        if (persistChanged) {
7442            schedulePersistUriGrants();
7443        }
7444    }
7445
7446    /**
7447     * @param uri This uri must NOT contain an embedded userId.
7448     * @param userId The userId in which the uri is to be resolved.
7449     */
7450    @Override
7451    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7452            int userId) {
7453        enforceNotIsolatedCaller("revokeUriPermission");
7454        synchronized(this) {
7455            final ProcessRecord r = getRecordForAppLocked(caller);
7456            if (r == null) {
7457                throw new SecurityException("Unable to find app for caller "
7458                        + caller
7459                        + " when revoking permission to uri " + uri);
7460            }
7461            if (uri == null) {
7462                Slog.w(TAG, "revokeUriPermission: null uri");
7463                return;
7464            }
7465
7466            if (!Intent.isAccessUriMode(modeFlags)) {
7467                return;
7468            }
7469
7470            final IPackageManager pm = AppGlobals.getPackageManager();
7471            final String authority = uri.getAuthority();
7472            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7473            if (pi == null) {
7474                Slog.w(TAG, "No content provider found for permission revoke: "
7475                        + uri.toSafeString());
7476                return;
7477            }
7478
7479            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7480        }
7481    }
7482
7483    /**
7484     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7485     * given package.
7486     *
7487     * @param packageName Package name to match, or {@code null} to apply to all
7488     *            packages.
7489     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7490     *            to all users.
7491     * @param persistable If persistable grants should be removed.
7492     */
7493    private void removeUriPermissionsForPackageLocked(
7494            String packageName, int userHandle, boolean persistable) {
7495        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7496            throw new IllegalArgumentException("Must narrow by either package or user");
7497        }
7498
7499        boolean persistChanged = false;
7500
7501        int N = mGrantedUriPermissions.size();
7502        for (int i = 0; i < N; i++) {
7503            final int targetUid = mGrantedUriPermissions.keyAt(i);
7504            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7505
7506            // Only inspect grants matching user
7507            if (userHandle == UserHandle.USER_ALL
7508                    || userHandle == UserHandle.getUserId(targetUid)) {
7509                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7510                    final UriPermission perm = it.next();
7511
7512                    // Only inspect grants matching package
7513                    if (packageName == null || perm.sourcePkg.equals(packageName)
7514                            || perm.targetPkg.equals(packageName)) {
7515                        persistChanged |= perm.revokeModes(persistable
7516                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7517
7518                        // Only remove when no modes remain; any persisted grants
7519                        // will keep this alive.
7520                        if (perm.modeFlags == 0) {
7521                            it.remove();
7522                        }
7523                    }
7524                }
7525
7526                if (perms.isEmpty()) {
7527                    mGrantedUriPermissions.remove(targetUid);
7528                    N--;
7529                    i--;
7530                }
7531            }
7532        }
7533
7534        if (persistChanged) {
7535            schedulePersistUriGrants();
7536        }
7537    }
7538
7539    @Override
7540    public IBinder newUriPermissionOwner(String name) {
7541        enforceNotIsolatedCaller("newUriPermissionOwner");
7542        synchronized(this) {
7543            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7544            return owner.getExternalTokenLocked();
7545        }
7546    }
7547
7548    /**
7549     * @param uri This uri must NOT contain an embedded userId.
7550     * @param sourceUserId The userId in which the uri is to be resolved.
7551     * @param targetUserId The userId of the app that receives the grant.
7552     */
7553    @Override
7554    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7555            final int modeFlags, int sourceUserId, int targetUserId) {
7556        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7557                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7558        synchronized(this) {
7559            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7560            if (owner == null) {
7561                throw new IllegalArgumentException("Unknown owner: " + token);
7562            }
7563            if (fromUid != Binder.getCallingUid()) {
7564                if (Binder.getCallingUid() != Process.myUid()) {
7565                    // Only system code can grant URI permissions on behalf
7566                    // of other users.
7567                    throw new SecurityException("nice try");
7568                }
7569            }
7570            if (targetPkg == null) {
7571                throw new IllegalArgumentException("null target");
7572            }
7573            if (uri == null) {
7574                throw new IllegalArgumentException("null uri");
7575            }
7576
7577            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7578                    modeFlags, owner, targetUserId);
7579        }
7580    }
7581
7582    /**
7583     * @param uri This uri must NOT contain an embedded userId.
7584     * @param userId The userId in which the uri is to be resolved.
7585     */
7586    @Override
7587    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7588        synchronized(this) {
7589            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7590            if (owner == null) {
7591                throw new IllegalArgumentException("Unknown owner: " + token);
7592            }
7593
7594            if (uri == null) {
7595                owner.removeUriPermissionsLocked(mode);
7596            } else {
7597                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7598            }
7599        }
7600    }
7601
7602    private void schedulePersistUriGrants() {
7603        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7604            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7605                    10 * DateUtils.SECOND_IN_MILLIS);
7606        }
7607    }
7608
7609    private void writeGrantedUriPermissions() {
7610        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7611
7612        // Snapshot permissions so we can persist without lock
7613        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7614        synchronized (this) {
7615            final int size = mGrantedUriPermissions.size();
7616            for (int i = 0; i < size; i++) {
7617                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7618                for (UriPermission perm : perms.values()) {
7619                    if (perm.persistedModeFlags != 0) {
7620                        persist.add(perm.snapshot());
7621                    }
7622                }
7623            }
7624        }
7625
7626        FileOutputStream fos = null;
7627        try {
7628            fos = mGrantFile.startWrite();
7629
7630            XmlSerializer out = new FastXmlSerializer();
7631            out.setOutput(fos, "utf-8");
7632            out.startDocument(null, true);
7633            out.startTag(null, TAG_URI_GRANTS);
7634            for (UriPermission.Snapshot perm : persist) {
7635                out.startTag(null, TAG_URI_GRANT);
7636                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7637                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7638                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7639                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7640                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7641                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7642                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7643                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7644                out.endTag(null, TAG_URI_GRANT);
7645            }
7646            out.endTag(null, TAG_URI_GRANTS);
7647            out.endDocument();
7648
7649            mGrantFile.finishWrite(fos);
7650        } catch (IOException e) {
7651            if (fos != null) {
7652                mGrantFile.failWrite(fos);
7653            }
7654        }
7655    }
7656
7657    private void readGrantedUriPermissionsLocked() {
7658        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7659
7660        final long now = System.currentTimeMillis();
7661
7662        FileInputStream fis = null;
7663        try {
7664            fis = mGrantFile.openRead();
7665            final XmlPullParser in = Xml.newPullParser();
7666            in.setInput(fis, null);
7667
7668            int type;
7669            while ((type = in.next()) != END_DOCUMENT) {
7670                final String tag = in.getName();
7671                if (type == START_TAG) {
7672                    if (TAG_URI_GRANT.equals(tag)) {
7673                        final int sourceUserId;
7674                        final int targetUserId;
7675                        final int userHandle = readIntAttribute(in,
7676                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7677                        if (userHandle != UserHandle.USER_NULL) {
7678                            // For backwards compatibility.
7679                            sourceUserId = userHandle;
7680                            targetUserId = userHandle;
7681                        } else {
7682                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7683                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7684                        }
7685                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7686                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7687                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7688                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7689                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7690                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7691
7692                        // Sanity check that provider still belongs to source package
7693                        final ProviderInfo pi = getProviderInfoLocked(
7694                                uri.getAuthority(), sourceUserId);
7695                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7696                            int targetUid = -1;
7697                            try {
7698                                targetUid = AppGlobals.getPackageManager()
7699                                        .getPackageUid(targetPkg, targetUserId);
7700                            } catch (RemoteException e) {
7701                            }
7702                            if (targetUid != -1) {
7703                                final UriPermission perm = findOrCreateUriPermissionLocked(
7704                                        sourcePkg, targetPkg, targetUid,
7705                                        new GrantUri(sourceUserId, uri, prefix));
7706                                perm.initPersistedModes(modeFlags, createdTime);
7707                            }
7708                        } else {
7709                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7710                                    + " but instead found " + pi);
7711                        }
7712                    }
7713                }
7714            }
7715        } catch (FileNotFoundException e) {
7716            // Missing grants is okay
7717        } catch (IOException e) {
7718            Slog.wtf(TAG, "Failed reading Uri grants", e);
7719        } catch (XmlPullParserException e) {
7720            Slog.wtf(TAG, "Failed reading Uri grants", e);
7721        } finally {
7722            IoUtils.closeQuietly(fis);
7723        }
7724    }
7725
7726    /**
7727     * @param uri This uri must NOT contain an embedded userId.
7728     * @param userId The userId in which the uri is to be resolved.
7729     */
7730    @Override
7731    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7732        enforceNotIsolatedCaller("takePersistableUriPermission");
7733
7734        Preconditions.checkFlagsArgument(modeFlags,
7735                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7736
7737        synchronized (this) {
7738            final int callingUid = Binder.getCallingUid();
7739            boolean persistChanged = false;
7740            GrantUri grantUri = new GrantUri(userId, uri, false);
7741
7742            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7743                    new GrantUri(userId, uri, false));
7744            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7745                    new GrantUri(userId, uri, true));
7746
7747            final boolean exactValid = (exactPerm != null)
7748                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7749            final boolean prefixValid = (prefixPerm != null)
7750                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7751
7752            if (!(exactValid || prefixValid)) {
7753                throw new SecurityException("No persistable permission grants found for UID "
7754                        + callingUid + " and Uri " + grantUri.toSafeString());
7755            }
7756
7757            if (exactValid) {
7758                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7759            }
7760            if (prefixValid) {
7761                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7762            }
7763
7764            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7765
7766            if (persistChanged) {
7767                schedulePersistUriGrants();
7768            }
7769        }
7770    }
7771
7772    /**
7773     * @param uri This uri must NOT contain an embedded userId.
7774     * @param userId The userId in which the uri is to be resolved.
7775     */
7776    @Override
7777    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7778        enforceNotIsolatedCaller("releasePersistableUriPermission");
7779
7780        Preconditions.checkFlagsArgument(modeFlags,
7781                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7782
7783        synchronized (this) {
7784            final int callingUid = Binder.getCallingUid();
7785            boolean persistChanged = false;
7786
7787            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7788                    new GrantUri(userId, uri, false));
7789            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7790                    new GrantUri(userId, uri, true));
7791            if (exactPerm == null && prefixPerm == null) {
7792                throw new SecurityException("No permission grants found for UID " + callingUid
7793                        + " and Uri " + uri.toSafeString());
7794            }
7795
7796            if (exactPerm != null) {
7797                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7798                removeUriPermissionIfNeededLocked(exactPerm);
7799            }
7800            if (prefixPerm != null) {
7801                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7802                removeUriPermissionIfNeededLocked(prefixPerm);
7803            }
7804
7805            if (persistChanged) {
7806                schedulePersistUriGrants();
7807            }
7808        }
7809    }
7810
7811    /**
7812     * Prune any older {@link UriPermission} for the given UID until outstanding
7813     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7814     *
7815     * @return if any mutations occured that require persisting.
7816     */
7817    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7818        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7819        if (perms == null) return false;
7820        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7821
7822        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7823        for (UriPermission perm : perms.values()) {
7824            if (perm.persistedModeFlags != 0) {
7825                persisted.add(perm);
7826            }
7827        }
7828
7829        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7830        if (trimCount <= 0) return false;
7831
7832        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7833        for (int i = 0; i < trimCount; i++) {
7834            final UriPermission perm = persisted.get(i);
7835
7836            if (DEBUG_URI_PERMISSION) {
7837                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7838            }
7839
7840            perm.releasePersistableModes(~0);
7841            removeUriPermissionIfNeededLocked(perm);
7842        }
7843
7844        return true;
7845    }
7846
7847    @Override
7848    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7849            String packageName, boolean incoming) {
7850        enforceNotIsolatedCaller("getPersistedUriPermissions");
7851        Preconditions.checkNotNull(packageName, "packageName");
7852
7853        final int callingUid = Binder.getCallingUid();
7854        final IPackageManager pm = AppGlobals.getPackageManager();
7855        try {
7856            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7857            if (packageUid != callingUid) {
7858                throw new SecurityException(
7859                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7860            }
7861        } catch (RemoteException e) {
7862            throw new SecurityException("Failed to verify package name ownership");
7863        }
7864
7865        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7866        synchronized (this) {
7867            if (incoming) {
7868                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7869                        callingUid);
7870                if (perms == null) {
7871                    Slog.w(TAG, "No permission grants found for " + packageName);
7872                } else {
7873                    for (UriPermission perm : perms.values()) {
7874                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7875                            result.add(perm.buildPersistedPublicApiObject());
7876                        }
7877                    }
7878                }
7879            } else {
7880                final int size = mGrantedUriPermissions.size();
7881                for (int i = 0; i < size; i++) {
7882                    final ArrayMap<GrantUri, UriPermission> perms =
7883                            mGrantedUriPermissions.valueAt(i);
7884                    for (UriPermission perm : perms.values()) {
7885                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7886                            result.add(perm.buildPersistedPublicApiObject());
7887                        }
7888                    }
7889                }
7890            }
7891        }
7892        return new ParceledListSlice<android.content.UriPermission>(result);
7893    }
7894
7895    @Override
7896    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7897        synchronized (this) {
7898            ProcessRecord app =
7899                who != null ? getRecordForAppLocked(who) : null;
7900            if (app == null) return;
7901
7902            Message msg = Message.obtain();
7903            msg.what = WAIT_FOR_DEBUGGER_MSG;
7904            msg.obj = app;
7905            msg.arg1 = waiting ? 1 : 0;
7906            mHandler.sendMessage(msg);
7907        }
7908    }
7909
7910    @Override
7911    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7912        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7913        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7914        outInfo.availMem = Process.getFreeMemory();
7915        outInfo.totalMem = Process.getTotalMemory();
7916        outInfo.threshold = homeAppMem;
7917        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7918        outInfo.hiddenAppThreshold = cachedAppMem;
7919        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7920                ProcessList.SERVICE_ADJ);
7921        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7922                ProcessList.VISIBLE_APP_ADJ);
7923        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7924                ProcessList.FOREGROUND_APP_ADJ);
7925    }
7926
7927    // =========================================================
7928    // TASK MANAGEMENT
7929    // =========================================================
7930
7931    @Override
7932    public List<IAppTask> getAppTasks(String callingPackage) {
7933        int callingUid = Binder.getCallingUid();
7934        long ident = Binder.clearCallingIdentity();
7935
7936        synchronized(this) {
7937            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7938            try {
7939                if (localLOGV) Slog.v(TAG, "getAppTasks");
7940
7941                final int N = mRecentTasks.size();
7942                for (int i = 0; i < N; i++) {
7943                    TaskRecord tr = mRecentTasks.get(i);
7944                    // Skip tasks that do not match the caller.  We don't need to verify
7945                    // callingPackage, because we are also limiting to callingUid and know
7946                    // that will limit to the correct security sandbox.
7947                    if (tr.effectiveUid != callingUid) {
7948                        continue;
7949                    }
7950                    Intent intent = tr.getBaseIntent();
7951                    if (intent == null ||
7952                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7953                        continue;
7954                    }
7955                    ActivityManager.RecentTaskInfo taskInfo =
7956                            createRecentTaskInfoFromTaskRecord(tr);
7957                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7958                    list.add(taskImpl);
7959                }
7960            } finally {
7961                Binder.restoreCallingIdentity(ident);
7962            }
7963            return list;
7964        }
7965    }
7966
7967    @Override
7968    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7969        final int callingUid = Binder.getCallingUid();
7970        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7971
7972        synchronized(this) {
7973            if (localLOGV) Slog.v(
7974                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7975
7976            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
7977                    callingUid);
7978
7979            // TODO: Improve with MRU list from all ActivityStacks.
7980            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7981        }
7982
7983        return list;
7984    }
7985
7986    TaskRecord getMostRecentTask() {
7987        return mRecentTasks.get(0);
7988    }
7989
7990    /**
7991     * Creates a new RecentTaskInfo from a TaskRecord.
7992     */
7993    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7994        // Update the task description to reflect any changes in the task stack
7995        tr.updateTaskDescription();
7996
7997        // Compose the recent task info
7998        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7999        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8000        rti.persistentId = tr.taskId;
8001        rti.baseIntent = new Intent(tr.getBaseIntent());
8002        rti.origActivity = tr.origActivity;
8003        rti.description = tr.lastDescription;
8004        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8005        rti.userId = tr.userId;
8006        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8007        rti.firstActiveTime = tr.firstActiveTime;
8008        rti.lastActiveTime = tr.lastActiveTime;
8009        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8010        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8011        return rti;
8012    }
8013
8014    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8015        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8016                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8017        if (!allowed) {
8018            if (checkPermission(android.Manifest.permission.GET_TASKS,
8019                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8020                // Temporary compatibility: some existing apps on the system image may
8021                // still be requesting the old permission and not switched to the new
8022                // one; if so, we'll still allow them full access.  This means we need
8023                // to see if they are holding the old permission and are a system app.
8024                try {
8025                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8026                        allowed = true;
8027                        Slog.w(TAG, caller + ": caller " + callingUid
8028                                + " is using old GET_TASKS but privileged; allowing");
8029                    }
8030                } catch (RemoteException e) {
8031                }
8032            }
8033        }
8034        if (!allowed) {
8035            Slog.w(TAG, caller + ": caller " + callingUid
8036                    + " does not hold GET_TASKS; limiting output");
8037        }
8038        return allowed;
8039    }
8040
8041    @Override
8042    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8043        final int callingUid = Binder.getCallingUid();
8044        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8045                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8046
8047        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8048        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8049        synchronized (this) {
8050            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8051                    callingUid);
8052            final boolean detailed = checkCallingPermission(
8053                    android.Manifest.permission.GET_DETAILED_TASKS)
8054                    == PackageManager.PERMISSION_GRANTED;
8055
8056            final int N = mRecentTasks.size();
8057            ArrayList<ActivityManager.RecentTaskInfo> res
8058                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8059                            maxNum < N ? maxNum : N);
8060
8061            final Set<Integer> includedUsers;
8062            if (includeProfiles) {
8063                includedUsers = getProfileIdsLocked(userId);
8064            } else {
8065                includedUsers = new HashSet<Integer>();
8066            }
8067            includedUsers.add(Integer.valueOf(userId));
8068
8069            for (int i=0; i<N && maxNum > 0; i++) {
8070                TaskRecord tr = mRecentTasks.get(i);
8071                // Only add calling user or related users recent tasks
8072                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8073                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8074                    continue;
8075                }
8076
8077                // Return the entry if desired by the caller.  We always return
8078                // the first entry, because callers always expect this to be the
8079                // foreground app.  We may filter others if the caller has
8080                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8081                // we should exclude the entry.
8082
8083                if (i == 0
8084                        || withExcluded
8085                        || (tr.intent == null)
8086                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8087                                == 0)) {
8088                    if (!allowed) {
8089                        // If the caller doesn't have the GET_TASKS permission, then only
8090                        // allow them to see a small subset of tasks -- their own and home.
8091                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8092                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8093                            continue;
8094                        }
8095                    }
8096                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8097                        if (tr.stack != null && tr.stack.isHomeStack()) {
8098                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8099                            continue;
8100                        }
8101                    }
8102                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8103                        // Don't include auto remove tasks that are finished or finishing.
8104                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8105                                + tr);
8106                        continue;
8107                    }
8108                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8109                            && !tr.isAvailable) {
8110                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8111                        continue;
8112                    }
8113
8114                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8115                    if (!detailed) {
8116                        rti.baseIntent.replaceExtras((Bundle)null);
8117                    }
8118
8119                    res.add(rti);
8120                    maxNum--;
8121                }
8122            }
8123            return res;
8124        }
8125    }
8126
8127    private TaskRecord taskForIdLocked(int id) {
8128        final TaskRecord task = recentTaskForIdLocked(id);
8129        if (task != null) {
8130            return task;
8131        }
8132
8133        // Don't give up. Sometimes it just hasn't made it to recents yet.
8134        return mStackSupervisor.anyTaskForIdLocked(id);
8135    }
8136
8137    private TaskRecord recentTaskForIdLocked(int id) {
8138        final int N = mRecentTasks.size();
8139            for (int i=0; i<N; i++) {
8140                TaskRecord tr = mRecentTasks.get(i);
8141                if (tr.taskId == id) {
8142                    return tr;
8143                }
8144            }
8145            return null;
8146    }
8147
8148    @Override
8149    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8150        synchronized (this) {
8151            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8152                    "getTaskThumbnail()");
8153            TaskRecord tr = recentTaskForIdLocked(id);
8154            if (tr != null) {
8155                return tr.getTaskThumbnailLocked();
8156            }
8157        }
8158        return null;
8159    }
8160
8161    @Override
8162    public int addAppTask(IBinder activityToken, Intent intent,
8163            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8164        final int callingUid = Binder.getCallingUid();
8165        final long callingIdent = Binder.clearCallingIdentity();
8166
8167        try {
8168            synchronized (this) {
8169                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8170                if (r == null) {
8171                    throw new IllegalArgumentException("Activity does not exist; token="
8172                            + activityToken);
8173                }
8174                ComponentName comp = intent.getComponent();
8175                if (comp == null) {
8176                    throw new IllegalArgumentException("Intent " + intent
8177                            + " must specify explicit component");
8178                }
8179                if (thumbnail.getWidth() != mThumbnailWidth
8180                        || thumbnail.getHeight() != mThumbnailHeight) {
8181                    throw new IllegalArgumentException("Bad thumbnail size: got "
8182                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8183                            + mThumbnailWidth + "x" + mThumbnailHeight);
8184                }
8185                if (intent.getSelector() != null) {
8186                    intent.setSelector(null);
8187                }
8188                if (intent.getSourceBounds() != null) {
8189                    intent.setSourceBounds(null);
8190                }
8191                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8192                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8193                        // The caller has added this as an auto-remove task...  that makes no
8194                        // sense, so turn off auto-remove.
8195                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8196                    }
8197                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8198                    // Must be a new task.
8199                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8200                }
8201                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8202                    mLastAddedTaskActivity = null;
8203                }
8204                ActivityInfo ainfo = mLastAddedTaskActivity;
8205                if (ainfo == null) {
8206                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8207                            comp, 0, UserHandle.getUserId(callingUid));
8208                    if (ainfo.applicationInfo.uid != callingUid) {
8209                        throw new SecurityException(
8210                                "Can't add task for another application: target uid="
8211                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8212                    }
8213                }
8214
8215                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8216                        intent, description);
8217
8218                int trimIdx = trimRecentsForTask(task, false);
8219                if (trimIdx >= 0) {
8220                    // If this would have caused a trim, then we'll abort because that
8221                    // means it would be added at the end of the list but then just removed.
8222                    return -1;
8223                }
8224
8225                final int N = mRecentTasks.size();
8226                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8227                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8228                    tr.removedFromRecents(mTaskPersister);
8229                }
8230
8231                task.inRecents = true;
8232                mRecentTasks.add(task);
8233                r.task.stack.addTask(task, false, false);
8234
8235                task.setLastThumbnail(thumbnail);
8236                task.freeLastThumbnail();
8237
8238                return task.taskId;
8239            }
8240        } finally {
8241            Binder.restoreCallingIdentity(callingIdent);
8242        }
8243    }
8244
8245    @Override
8246    public Point getAppTaskThumbnailSize() {
8247        synchronized (this) {
8248            return new Point(mThumbnailWidth,  mThumbnailHeight);
8249        }
8250    }
8251
8252    @Override
8253    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8254        synchronized (this) {
8255            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8256            if (r != null) {
8257                r.setTaskDescription(td);
8258                r.task.updateTaskDescription();
8259            }
8260        }
8261    }
8262
8263    @Override
8264    public Bitmap getTaskDescriptionIcon(String filename) {
8265        if (!FileUtils.isValidExtFilename(filename)
8266                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8267            throw new IllegalArgumentException("Bad filename: " + filename);
8268        }
8269        return mTaskPersister.getTaskDescriptionIcon(filename);
8270    }
8271
8272    @Override
8273    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8274            throws RemoteException {
8275        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8276                opts.getCustomInPlaceResId() == 0) {
8277            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8278                    "with valid animation");
8279        }
8280        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8281        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8282                opts.getCustomInPlaceResId());
8283        mWindowManager.executeAppTransition();
8284    }
8285
8286    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8287        mRecentTasks.remove(tr);
8288        tr.removedFromRecents(mTaskPersister);
8289        ComponentName component = tr.getBaseIntent().getComponent();
8290        if (component == null) {
8291            Slog.w(TAG, "No component for base intent of task: " + tr);
8292            return;
8293        }
8294
8295        if (!killProcess) {
8296            return;
8297        }
8298
8299        // Determine if the process(es) for this task should be killed.
8300        final String pkg = component.getPackageName();
8301        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8302        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8303        for (int i = 0; i < pmap.size(); i++) {
8304
8305            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8306            for (int j = 0; j < uids.size(); j++) {
8307                ProcessRecord proc = uids.valueAt(j);
8308                if (proc.userId != tr.userId) {
8309                    // Don't kill process for a different user.
8310                    continue;
8311                }
8312                if (proc == mHomeProcess) {
8313                    // Don't kill the home process along with tasks from the same package.
8314                    continue;
8315                }
8316                if (!proc.pkgList.containsKey(pkg)) {
8317                    // Don't kill process that is not associated with this task.
8318                    continue;
8319                }
8320
8321                for (int k = 0; k < proc.activities.size(); k++) {
8322                    TaskRecord otherTask = proc.activities.get(k).task;
8323                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8324                        // Don't kill process(es) that has an activity in a different task that is
8325                        // also in recents.
8326                        return;
8327                    }
8328                }
8329
8330                // Add process to kill list.
8331                procsToKill.add(proc);
8332            }
8333        }
8334
8335        // Find any running services associated with this app and stop if needed.
8336        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8337
8338        // Kill the running processes.
8339        for (int i = 0; i < procsToKill.size(); i++) {
8340            ProcessRecord pr = procsToKill.get(i);
8341            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8342                pr.kill("remove task", true);
8343            } else {
8344                pr.waitingToKill = "remove task";
8345            }
8346        }
8347    }
8348
8349    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8350        // Remove all tasks with activities in the specified package from the list of recent tasks
8351        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8352            TaskRecord tr = mRecentTasks.get(i);
8353            if (tr.userId != userId) continue;
8354
8355            ComponentName cn = tr.intent.getComponent();
8356            if (cn != null && cn.getPackageName().equals(packageName)) {
8357                // If the package name matches, remove the task.
8358                removeTaskByIdLocked(tr.taskId, true);
8359            }
8360        }
8361    }
8362
8363    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8364        final IPackageManager pm = AppGlobals.getPackageManager();
8365        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8366
8367        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8368            TaskRecord tr = mRecentTasks.get(i);
8369            if (tr.userId != userId) continue;
8370
8371            ComponentName cn = tr.intent.getComponent();
8372            if (cn != null && cn.getPackageName().equals(packageName)) {
8373                // Skip if component still exists in the package.
8374                if (componentsKnownToExist.contains(cn)) continue;
8375
8376                try {
8377                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8378                    if (info != null) {
8379                        componentsKnownToExist.add(cn);
8380                    } else {
8381                        removeTaskByIdLocked(tr.taskId, false);
8382                    }
8383                } catch (RemoteException e) {
8384                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8385                }
8386            }
8387        }
8388    }
8389
8390    /**
8391     * Removes the task with the specified task id.
8392     *
8393     * @param taskId Identifier of the task to be removed.
8394     * @param killProcess Kill any process associated with the task if possible.
8395     * @return Returns true if the given task was found and removed.
8396     */
8397    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8398        TaskRecord tr = taskForIdLocked(taskId);
8399        if (tr != null) {
8400            tr.removeTaskActivitiesLocked();
8401            cleanUpRemovedTaskLocked(tr, killProcess);
8402            if (tr.isPersistable) {
8403                notifyTaskPersisterLocked(null, true);
8404            }
8405            return true;
8406        }
8407        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8408        return false;
8409    }
8410
8411    @Override
8412    public boolean removeTask(int taskId) {
8413        synchronized (this) {
8414            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8415                    "removeTask()");
8416            long ident = Binder.clearCallingIdentity();
8417            try {
8418                return removeTaskByIdLocked(taskId, true);
8419            } finally {
8420                Binder.restoreCallingIdentity(ident);
8421            }
8422        }
8423    }
8424
8425    /**
8426     * TODO: Add mController hook
8427     */
8428    @Override
8429    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8430        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8431                "moveTaskToFront()");
8432
8433        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8434        synchronized(this) {
8435            moveTaskToFrontLocked(taskId, flags, options);
8436        }
8437    }
8438
8439    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8440        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8441                Binder.getCallingUid(), -1, -1, "Task to front")) {
8442            ActivityOptions.abort(options);
8443            return;
8444        }
8445        final long origId = Binder.clearCallingIdentity();
8446        try {
8447            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8448            if (task == null) {
8449                Slog.d(TAG, "Could not find task for id: "+ taskId);
8450                return;
8451            }
8452            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8453                mStackSupervisor.showLockTaskToast();
8454                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8455                return;
8456            }
8457            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8458            if (prev != null && prev.isRecentsActivity()) {
8459                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8460            }
8461            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8462        } finally {
8463            Binder.restoreCallingIdentity(origId);
8464        }
8465        ActivityOptions.abort(options);
8466    }
8467
8468    @Override
8469    public void moveTaskToBack(int taskId) {
8470        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8471                "moveTaskToBack()");
8472
8473        synchronized(this) {
8474            TaskRecord tr = taskForIdLocked(taskId);
8475            if (tr != null) {
8476                if (tr == mStackSupervisor.mLockTaskModeTask) {
8477                    mStackSupervisor.showLockTaskToast();
8478                    return;
8479                }
8480                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8481                ActivityStack stack = tr.stack;
8482                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8483                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8484                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8485                        return;
8486                    }
8487                }
8488                final long origId = Binder.clearCallingIdentity();
8489                try {
8490                    stack.moveTaskToBackLocked(taskId, null);
8491                } finally {
8492                    Binder.restoreCallingIdentity(origId);
8493                }
8494            }
8495        }
8496    }
8497
8498    /**
8499     * Moves an activity, and all of the other activities within the same task, to the bottom
8500     * of the history stack.  The activity's order within the task is unchanged.
8501     *
8502     * @param token A reference to the activity we wish to move
8503     * @param nonRoot If false then this only works if the activity is the root
8504     *                of a task; if true it will work for any activity in a task.
8505     * @return Returns true if the move completed, false if not.
8506     */
8507    @Override
8508    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8509        enforceNotIsolatedCaller("moveActivityTaskToBack");
8510        synchronized(this) {
8511            final long origId = Binder.clearCallingIdentity();
8512            try {
8513                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8514                if (taskId >= 0) {
8515                    if ((mStackSupervisor.mLockTaskModeTask != null)
8516                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8517                        mStackSupervisor.showLockTaskToast();
8518                        return false;
8519                    }
8520                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8521                }
8522            } finally {
8523                Binder.restoreCallingIdentity(origId);
8524            }
8525        }
8526        return false;
8527    }
8528
8529    @Override
8530    public void moveTaskBackwards(int task) {
8531        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8532                "moveTaskBackwards()");
8533
8534        synchronized(this) {
8535            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8536                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8537                return;
8538            }
8539            final long origId = Binder.clearCallingIdentity();
8540            moveTaskBackwardsLocked(task);
8541            Binder.restoreCallingIdentity(origId);
8542        }
8543    }
8544
8545    private final void moveTaskBackwardsLocked(int task) {
8546        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8547    }
8548
8549    @Override
8550    public IBinder getHomeActivityToken() throws RemoteException {
8551        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8552                "getHomeActivityToken()");
8553        synchronized (this) {
8554            return mStackSupervisor.getHomeActivityToken();
8555        }
8556    }
8557
8558    @Override
8559    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8560            IActivityContainerCallback callback) throws RemoteException {
8561        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8562                "createActivityContainer()");
8563        synchronized (this) {
8564            if (parentActivityToken == null) {
8565                throw new IllegalArgumentException("parent token must not be null");
8566            }
8567            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8568            if (r == null) {
8569                return null;
8570            }
8571            if (callback == null) {
8572                throw new IllegalArgumentException("callback must not be null");
8573            }
8574            return mStackSupervisor.createActivityContainer(r, callback);
8575        }
8576    }
8577
8578    @Override
8579    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8580        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8581                "deleteActivityContainer()");
8582        synchronized (this) {
8583            mStackSupervisor.deleteActivityContainer(container);
8584        }
8585    }
8586
8587    @Override
8588    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8589            throws RemoteException {
8590        synchronized (this) {
8591            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8592            if (stack != null) {
8593                return stack.mActivityContainer;
8594            }
8595            return null;
8596        }
8597    }
8598
8599    @Override
8600    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8601        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8602                "moveTaskToStack()");
8603        if (stackId == HOME_STACK_ID) {
8604            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8605                    new RuntimeException("here").fillInStackTrace());
8606        }
8607        synchronized (this) {
8608            long ident = Binder.clearCallingIdentity();
8609            try {
8610                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8611                        + stackId + " toTop=" + toTop);
8612                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8613            } finally {
8614                Binder.restoreCallingIdentity(ident);
8615            }
8616        }
8617    }
8618
8619    @Override
8620    public void resizeStack(int stackBoxId, Rect bounds) {
8621        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8622                "resizeStackBox()");
8623        long ident = Binder.clearCallingIdentity();
8624        try {
8625            mWindowManager.resizeStack(stackBoxId, bounds);
8626        } finally {
8627            Binder.restoreCallingIdentity(ident);
8628        }
8629    }
8630
8631    @Override
8632    public List<StackInfo> getAllStackInfos() {
8633        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8634                "getAllStackInfos()");
8635        long ident = Binder.clearCallingIdentity();
8636        try {
8637            synchronized (this) {
8638                return mStackSupervisor.getAllStackInfosLocked();
8639            }
8640        } finally {
8641            Binder.restoreCallingIdentity(ident);
8642        }
8643    }
8644
8645    @Override
8646    public StackInfo getStackInfo(int stackId) {
8647        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8648                "getStackInfo()");
8649        long ident = Binder.clearCallingIdentity();
8650        try {
8651            synchronized (this) {
8652                return mStackSupervisor.getStackInfoLocked(stackId);
8653            }
8654        } finally {
8655            Binder.restoreCallingIdentity(ident);
8656        }
8657    }
8658
8659    @Override
8660    public boolean isInHomeStack(int taskId) {
8661        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8662                "getStackInfo()");
8663        long ident = Binder.clearCallingIdentity();
8664        try {
8665            synchronized (this) {
8666                TaskRecord tr = taskForIdLocked(taskId);
8667                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8668            }
8669        } finally {
8670            Binder.restoreCallingIdentity(ident);
8671        }
8672    }
8673
8674    @Override
8675    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8676        synchronized(this) {
8677            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8678        }
8679    }
8680
8681    private boolean isLockTaskAuthorized(String pkg) {
8682        final DevicePolicyManager dpm = (DevicePolicyManager)
8683                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8684        try {
8685            int uid = mContext.getPackageManager().getPackageUid(pkg,
8686                    Binder.getCallingUserHandle().getIdentifier());
8687            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8688        } catch (NameNotFoundException e) {
8689            return false;
8690        }
8691    }
8692
8693    void startLockTaskMode(TaskRecord task) {
8694        final String pkg;
8695        synchronized (this) {
8696            pkg = task.intent.getComponent().getPackageName();
8697        }
8698        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8699        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8700            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8701                    StatusBarManagerInternal.class);
8702            if (statusBarManager != null) {
8703                statusBarManager.showScreenPinningRequest();
8704            }
8705            return;
8706        }
8707        long ident = Binder.clearCallingIdentity();
8708        try {
8709            synchronized (this) {
8710                // Since we lost lock on task, make sure it is still there.
8711                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8712                if (task != null) {
8713                    if (!isSystemInitiated
8714                            && ((mStackSupervisor.getFocusedStack() == null)
8715                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8716                        throw new IllegalArgumentException("Invalid task, not in foreground");
8717                    }
8718                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8719                }
8720            }
8721        } finally {
8722            Binder.restoreCallingIdentity(ident);
8723        }
8724    }
8725
8726    @Override
8727    public void startLockTaskMode(int taskId) {
8728        final TaskRecord task;
8729        long ident = Binder.clearCallingIdentity();
8730        try {
8731            synchronized (this) {
8732                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8733            }
8734        } finally {
8735            Binder.restoreCallingIdentity(ident);
8736        }
8737        if (task != null) {
8738            startLockTaskMode(task);
8739        }
8740    }
8741
8742    @Override
8743    public void startLockTaskMode(IBinder token) {
8744        final TaskRecord task;
8745        long ident = Binder.clearCallingIdentity();
8746        try {
8747            synchronized (this) {
8748                final ActivityRecord r = ActivityRecord.forToken(token);
8749                if (r == null) {
8750                    return;
8751                }
8752                task = r.task;
8753            }
8754        } finally {
8755            Binder.restoreCallingIdentity(ident);
8756        }
8757        if (task != null) {
8758            startLockTaskMode(task);
8759        }
8760    }
8761
8762    @Override
8763    public void startLockTaskModeOnCurrent() throws RemoteException {
8764        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8765                "startLockTaskModeOnCurrent");
8766        long ident = Binder.clearCallingIdentity();
8767        try {
8768            ActivityRecord r = null;
8769            synchronized (this) {
8770                r = mStackSupervisor.topRunningActivityLocked();
8771            }
8772            startLockTaskMode(r.task);
8773        } finally {
8774            Binder.restoreCallingIdentity(ident);
8775        }
8776    }
8777
8778    @Override
8779    public void stopLockTaskMode() {
8780        // Verify that the user matches the package of the intent for the TaskRecord
8781        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8782        // and stopLockTaskMode.
8783        final int callingUid = Binder.getCallingUid();
8784        if (callingUid != Process.SYSTEM_UID) {
8785            try {
8786                String pkg =
8787                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8788                int uid = mContext.getPackageManager().getPackageUid(pkg,
8789                        Binder.getCallingUserHandle().getIdentifier());
8790                if (uid != callingUid) {
8791                    throw new SecurityException("Invalid uid, expected " + uid);
8792                }
8793            } catch (NameNotFoundException e) {
8794                Log.d(TAG, "stopLockTaskMode " + e);
8795                return;
8796            }
8797        }
8798        long ident = Binder.clearCallingIdentity();
8799        try {
8800            Log.d(TAG, "stopLockTaskMode");
8801            // Stop lock task
8802            synchronized (this) {
8803                mStackSupervisor.setLockTaskModeLocked(null, false);
8804            }
8805        } finally {
8806            Binder.restoreCallingIdentity(ident);
8807        }
8808    }
8809
8810    @Override
8811    public void stopLockTaskModeOnCurrent() throws RemoteException {
8812        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8813                "stopLockTaskModeOnCurrent");
8814        long ident = Binder.clearCallingIdentity();
8815        try {
8816            stopLockTaskMode();
8817        } finally {
8818            Binder.restoreCallingIdentity(ident);
8819        }
8820    }
8821
8822    @Override
8823    public boolean isInLockTaskMode() {
8824        synchronized (this) {
8825            return mStackSupervisor.isInLockTaskMode();
8826        }
8827    }
8828
8829    // =========================================================
8830    // CONTENT PROVIDERS
8831    // =========================================================
8832
8833    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8834        List<ProviderInfo> providers = null;
8835        try {
8836            providers = AppGlobals.getPackageManager().
8837                queryContentProviders(app.processName, app.uid,
8838                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8839        } catch (RemoteException ex) {
8840        }
8841        if (DEBUG_MU)
8842            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8843        int userId = app.userId;
8844        if (providers != null) {
8845            int N = providers.size();
8846            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8847            for (int i=0; i<N; i++) {
8848                ProviderInfo cpi =
8849                    (ProviderInfo)providers.get(i);
8850                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8851                        cpi.name, cpi.flags);
8852                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8853                    // This is a singleton provider, but a user besides the
8854                    // default user is asking to initialize a process it runs
8855                    // in...  well, no, it doesn't actually run in this process,
8856                    // it runs in the process of the default user.  Get rid of it.
8857                    providers.remove(i);
8858                    N--;
8859                    i--;
8860                    continue;
8861                }
8862
8863                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8864                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8865                if (cpr == null) {
8866                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8867                    mProviderMap.putProviderByClass(comp, cpr);
8868                }
8869                if (DEBUG_MU)
8870                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8871                app.pubProviders.put(cpi.name, cpr);
8872                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8873                    // Don't add this if it is a platform component that is marked
8874                    // to run in multiple processes, because this is actually
8875                    // part of the framework so doesn't make sense to track as a
8876                    // separate apk in the process.
8877                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8878                            mProcessStats);
8879                }
8880                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8881            }
8882        }
8883        return providers;
8884    }
8885
8886    /**
8887     * Check if {@link ProcessRecord} has a possible chance at accessing the
8888     * given {@link ProviderInfo}. Final permission checking is always done
8889     * in {@link ContentProvider}.
8890     */
8891    private final String checkContentProviderPermissionLocked(
8892            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8893        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8894        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8895        boolean checkedGrants = false;
8896        if (checkUser) {
8897            // Looking for cross-user grants before enforcing the typical cross-users permissions
8898            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8899            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8900                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8901                    return null;
8902                }
8903                checkedGrants = true;
8904            }
8905            userId = handleIncomingUser(callingPid, callingUid, userId,
8906                    false, ALLOW_NON_FULL,
8907                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8908            if (userId != tmpTargetUserId) {
8909                // When we actually went to determine the final targer user ID, this ended
8910                // up different than our initial check for the authority.  This is because
8911                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8912                // SELF.  So we need to re-check the grants again.
8913                checkedGrants = false;
8914            }
8915        }
8916        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8917                cpi.applicationInfo.uid, cpi.exported)
8918                == PackageManager.PERMISSION_GRANTED) {
8919            return null;
8920        }
8921        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8922                cpi.applicationInfo.uid, cpi.exported)
8923                == PackageManager.PERMISSION_GRANTED) {
8924            return null;
8925        }
8926
8927        PathPermission[] pps = cpi.pathPermissions;
8928        if (pps != null) {
8929            int i = pps.length;
8930            while (i > 0) {
8931                i--;
8932                PathPermission pp = pps[i];
8933                String pprperm = pp.getReadPermission();
8934                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8935                        cpi.applicationInfo.uid, cpi.exported)
8936                        == PackageManager.PERMISSION_GRANTED) {
8937                    return null;
8938                }
8939                String ppwperm = pp.getWritePermission();
8940                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8941                        cpi.applicationInfo.uid, cpi.exported)
8942                        == PackageManager.PERMISSION_GRANTED) {
8943                    return null;
8944                }
8945            }
8946        }
8947        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8948            return null;
8949        }
8950
8951        String msg;
8952        if (!cpi.exported) {
8953            msg = "Permission Denial: opening provider " + cpi.name
8954                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8955                    + ", uid=" + callingUid + ") that is not exported from uid "
8956                    + cpi.applicationInfo.uid;
8957        } else {
8958            msg = "Permission Denial: opening provider " + cpi.name
8959                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8960                    + ", uid=" + callingUid + ") requires "
8961                    + cpi.readPermission + " or " + cpi.writePermission;
8962        }
8963        Slog.w(TAG, msg);
8964        return msg;
8965    }
8966
8967    /**
8968     * Returns if the ContentProvider has granted a uri to callingUid
8969     */
8970    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8971        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8972        if (perms != null) {
8973            for (int i=perms.size()-1; i>=0; i--) {
8974                GrantUri grantUri = perms.keyAt(i);
8975                if (grantUri.sourceUserId == userId || !checkUser) {
8976                    if (matchesProvider(grantUri.uri, cpi)) {
8977                        return true;
8978                    }
8979                }
8980            }
8981        }
8982        return false;
8983    }
8984
8985    /**
8986     * Returns true if the uri authority is one of the authorities specified in the provider.
8987     */
8988    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8989        String uriAuth = uri.getAuthority();
8990        String cpiAuth = cpi.authority;
8991        if (cpiAuth.indexOf(';') == -1) {
8992            return cpiAuth.equals(uriAuth);
8993        }
8994        String[] cpiAuths = cpiAuth.split(";");
8995        int length = cpiAuths.length;
8996        for (int i = 0; i < length; i++) {
8997            if (cpiAuths[i].equals(uriAuth)) return true;
8998        }
8999        return false;
9000    }
9001
9002    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9003            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9004        if (r != null) {
9005            for (int i=0; i<r.conProviders.size(); i++) {
9006                ContentProviderConnection conn = r.conProviders.get(i);
9007                if (conn.provider == cpr) {
9008                    if (DEBUG_PROVIDER) Slog.v(TAG,
9009                            "Adding provider requested by "
9010                            + r.processName + " from process "
9011                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9012                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9013                    if (stable) {
9014                        conn.stableCount++;
9015                        conn.numStableIncs++;
9016                    } else {
9017                        conn.unstableCount++;
9018                        conn.numUnstableIncs++;
9019                    }
9020                    return conn;
9021                }
9022            }
9023            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9024            if (stable) {
9025                conn.stableCount = 1;
9026                conn.numStableIncs = 1;
9027            } else {
9028                conn.unstableCount = 1;
9029                conn.numUnstableIncs = 1;
9030            }
9031            cpr.connections.add(conn);
9032            r.conProviders.add(conn);
9033            return conn;
9034        }
9035        cpr.addExternalProcessHandleLocked(externalProcessToken);
9036        return null;
9037    }
9038
9039    boolean decProviderCountLocked(ContentProviderConnection conn,
9040            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9041        if (conn != null) {
9042            cpr = conn.provider;
9043            if (DEBUG_PROVIDER) Slog.v(TAG,
9044                    "Removing provider requested by "
9045                    + conn.client.processName + " from process "
9046                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9047                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9048            if (stable) {
9049                conn.stableCount--;
9050            } else {
9051                conn.unstableCount--;
9052            }
9053            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9054                cpr.connections.remove(conn);
9055                conn.client.conProviders.remove(conn);
9056                return true;
9057            }
9058            return false;
9059        }
9060        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9061        return false;
9062    }
9063
9064    private void checkTime(long startTime, String where) {
9065        long now = SystemClock.elapsedRealtime();
9066        if ((now-startTime) > 1000) {
9067            // If we are taking more than a second, log about it.
9068            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9069        }
9070    }
9071
9072    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9073            String name, IBinder token, boolean stable, int userId) {
9074        ContentProviderRecord cpr;
9075        ContentProviderConnection conn = null;
9076        ProviderInfo cpi = null;
9077
9078        synchronized(this) {
9079            long startTime = SystemClock.elapsedRealtime();
9080
9081            ProcessRecord r = null;
9082            if (caller != null) {
9083                r = getRecordForAppLocked(caller);
9084                if (r == null) {
9085                    throw new SecurityException(
9086                            "Unable to find app for caller " + caller
9087                          + " (pid=" + Binder.getCallingPid()
9088                          + ") when getting content provider " + name);
9089                }
9090            }
9091
9092            boolean checkCrossUser = true;
9093
9094            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9095
9096            // First check if this content provider has been published...
9097            cpr = mProviderMap.getProviderByName(name, userId);
9098            // If that didn't work, check if it exists for user 0 and then
9099            // verify that it's a singleton provider before using it.
9100            if (cpr == null && userId != UserHandle.USER_OWNER) {
9101                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9102                if (cpr != null) {
9103                    cpi = cpr.info;
9104                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9105                            cpi.name, cpi.flags)
9106                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9107                        userId = UserHandle.USER_OWNER;
9108                        checkCrossUser = false;
9109                    } else {
9110                        cpr = null;
9111                        cpi = null;
9112                    }
9113                }
9114            }
9115
9116            boolean providerRunning = cpr != null;
9117            if (providerRunning) {
9118                cpi = cpr.info;
9119                String msg;
9120                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9121                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9122                        != null) {
9123                    throw new SecurityException(msg);
9124                }
9125                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9126
9127                if (r != null && cpr.canRunHere(r)) {
9128                    // This provider has been published or is in the process
9129                    // of being published...  but it is also allowed to run
9130                    // in the caller's process, so don't make a connection
9131                    // and just let the caller instantiate its own instance.
9132                    ContentProviderHolder holder = cpr.newHolder(null);
9133                    // don't give caller the provider object, it needs
9134                    // to make its own.
9135                    holder.provider = null;
9136                    return holder;
9137                }
9138
9139                final long origId = Binder.clearCallingIdentity();
9140
9141                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9142
9143                // In this case the provider instance already exists, so we can
9144                // return it right away.
9145                conn = incProviderCountLocked(r, cpr, token, stable);
9146                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9147                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9148                        // If this is a perceptible app accessing the provider,
9149                        // make sure to count it as being accessed and thus
9150                        // back up on the LRU list.  This is good because
9151                        // content providers are often expensive to start.
9152                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9153                        updateLruProcessLocked(cpr.proc, false, null);
9154                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9155                    }
9156                }
9157
9158                if (cpr.proc != null) {
9159                    if (false) {
9160                        if (cpr.name.flattenToShortString().equals(
9161                                "com.android.providers.calendar/.CalendarProvider2")) {
9162                            Slog.v(TAG, "****************** KILLING "
9163                                + cpr.name.flattenToShortString());
9164                            Process.killProcess(cpr.proc.pid);
9165                        }
9166                    }
9167                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9168                    boolean success = updateOomAdjLocked(cpr.proc);
9169                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9170                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9171                    // NOTE: there is still a race here where a signal could be
9172                    // pending on the process even though we managed to update its
9173                    // adj level.  Not sure what to do about this, but at least
9174                    // the race is now smaller.
9175                    if (!success) {
9176                        // Uh oh...  it looks like the provider's process
9177                        // has been killed on us.  We need to wait for a new
9178                        // process to be started, and make sure its death
9179                        // doesn't kill our process.
9180                        Slog.i(TAG,
9181                                "Existing provider " + cpr.name.flattenToShortString()
9182                                + " is crashing; detaching " + r);
9183                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9184                        checkTime(startTime, "getContentProviderImpl: before appDied");
9185                        appDiedLocked(cpr.proc);
9186                        checkTime(startTime, "getContentProviderImpl: after appDied");
9187                        if (!lastRef) {
9188                            // This wasn't the last ref our process had on
9189                            // the provider...  we have now been killed, bail.
9190                            return null;
9191                        }
9192                        providerRunning = false;
9193                        conn = null;
9194                    }
9195                }
9196
9197                Binder.restoreCallingIdentity(origId);
9198            }
9199
9200            boolean singleton;
9201            if (!providerRunning) {
9202                try {
9203                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9204                    cpi = AppGlobals.getPackageManager().
9205                        resolveContentProvider(name,
9206                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9207                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9208                } catch (RemoteException ex) {
9209                }
9210                if (cpi == null) {
9211                    return null;
9212                }
9213                // If the provider is a singleton AND
9214                // (it's a call within the same user || the provider is a
9215                // privileged app)
9216                // Then allow connecting to the singleton provider
9217                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9218                        cpi.name, cpi.flags)
9219                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9220                if (singleton) {
9221                    userId = UserHandle.USER_OWNER;
9222                }
9223                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9224                checkTime(startTime, "getContentProviderImpl: got app info for user");
9225
9226                String msg;
9227                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9228                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9229                        != null) {
9230                    throw new SecurityException(msg);
9231                }
9232                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9233
9234                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9235                        && !cpi.processName.equals("system")) {
9236                    // If this content provider does not run in the system
9237                    // process, and the system is not yet ready to run other
9238                    // processes, then fail fast instead of hanging.
9239                    throw new IllegalArgumentException(
9240                            "Attempt to launch content provider before system ready");
9241                }
9242
9243                // Make sure that the user who owns this provider is started.  If not,
9244                // we don't want to allow it to run.
9245                if (mStartedUsers.get(userId) == null) {
9246                    Slog.w(TAG, "Unable to launch app "
9247                            + cpi.applicationInfo.packageName + "/"
9248                            + cpi.applicationInfo.uid + " for provider "
9249                            + name + ": user " + userId + " is stopped");
9250                    return null;
9251                }
9252
9253                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9254                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9255                cpr = mProviderMap.getProviderByClass(comp, userId);
9256                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9257                final boolean firstClass = cpr == null;
9258                if (firstClass) {
9259                    final long ident = Binder.clearCallingIdentity();
9260                    try {
9261                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9262                        ApplicationInfo ai =
9263                            AppGlobals.getPackageManager().
9264                                getApplicationInfo(
9265                                        cpi.applicationInfo.packageName,
9266                                        STOCK_PM_FLAGS, userId);
9267                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9268                        if (ai == null) {
9269                            Slog.w(TAG, "No package info for content provider "
9270                                    + cpi.name);
9271                            return null;
9272                        }
9273                        ai = getAppInfoForUser(ai, userId);
9274                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9275                    } catch (RemoteException ex) {
9276                        // pm is in same process, this will never happen.
9277                    } finally {
9278                        Binder.restoreCallingIdentity(ident);
9279                    }
9280                }
9281
9282                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9283
9284                if (r != null && cpr.canRunHere(r)) {
9285                    // If this is a multiprocess provider, then just return its
9286                    // info and allow the caller to instantiate it.  Only do
9287                    // this if the provider is the same user as the caller's
9288                    // process, or can run as root (so can be in any process).
9289                    return cpr.newHolder(null);
9290                }
9291
9292                if (DEBUG_PROVIDER) {
9293                    RuntimeException e = new RuntimeException("here");
9294                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9295                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9296                }
9297
9298                // This is single process, and our app is now connecting to it.
9299                // See if we are already in the process of launching this
9300                // provider.
9301                final int N = mLaunchingProviders.size();
9302                int i;
9303                for (i=0; i<N; i++) {
9304                    if (mLaunchingProviders.get(i) == cpr) {
9305                        break;
9306                    }
9307                }
9308
9309                // If the provider is not already being launched, then get it
9310                // started.
9311                if (i >= N) {
9312                    final long origId = Binder.clearCallingIdentity();
9313
9314                    try {
9315                        // Content provider is now in use, its package can't be stopped.
9316                        try {
9317                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9318                            AppGlobals.getPackageManager().setPackageStoppedState(
9319                                    cpr.appInfo.packageName, false, userId);
9320                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9321                        } catch (RemoteException e) {
9322                        } catch (IllegalArgumentException e) {
9323                            Slog.w(TAG, "Failed trying to unstop package "
9324                                    + cpr.appInfo.packageName + ": " + e);
9325                        }
9326
9327                        // Use existing process if already started
9328                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9329                        ProcessRecord proc = getProcessRecordLocked(
9330                                cpi.processName, cpr.appInfo.uid, false);
9331                        if (proc != null && proc.thread != null) {
9332                            if (DEBUG_PROVIDER) {
9333                                Slog.d(TAG, "Installing in existing process " + proc);
9334                            }
9335                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9336                            proc.pubProviders.put(cpi.name, cpr);
9337                            try {
9338                                proc.thread.scheduleInstallProvider(cpi);
9339                            } catch (RemoteException e) {
9340                            }
9341                        } else {
9342                            checkTime(startTime, "getContentProviderImpl: before start process");
9343                            proc = startProcessLocked(cpi.processName,
9344                                    cpr.appInfo, false, 0, "content provider",
9345                                    new ComponentName(cpi.applicationInfo.packageName,
9346                                            cpi.name), false, false, false);
9347                            checkTime(startTime, "getContentProviderImpl: after start process");
9348                            if (proc == null) {
9349                                Slog.w(TAG, "Unable to launch app "
9350                                        + cpi.applicationInfo.packageName + "/"
9351                                        + cpi.applicationInfo.uid + " for provider "
9352                                        + name + ": process is bad");
9353                                return null;
9354                            }
9355                        }
9356                        cpr.launchingApp = proc;
9357                        mLaunchingProviders.add(cpr);
9358                    } finally {
9359                        Binder.restoreCallingIdentity(origId);
9360                    }
9361                }
9362
9363                checkTime(startTime, "getContentProviderImpl: updating data structures");
9364
9365                // Make sure the provider is published (the same provider class
9366                // may be published under multiple names).
9367                if (firstClass) {
9368                    mProviderMap.putProviderByClass(comp, cpr);
9369                }
9370
9371                mProviderMap.putProviderByName(name, cpr);
9372                conn = incProviderCountLocked(r, cpr, token, stable);
9373                if (conn != null) {
9374                    conn.waiting = true;
9375                }
9376            }
9377            checkTime(startTime, "getContentProviderImpl: done!");
9378        }
9379
9380        // Wait for the provider to be published...
9381        synchronized (cpr) {
9382            while (cpr.provider == null) {
9383                if (cpr.launchingApp == null) {
9384                    Slog.w(TAG, "Unable to launch app "
9385                            + cpi.applicationInfo.packageName + "/"
9386                            + cpi.applicationInfo.uid + " for provider "
9387                            + name + ": launching app became null");
9388                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9389                            UserHandle.getUserId(cpi.applicationInfo.uid),
9390                            cpi.applicationInfo.packageName,
9391                            cpi.applicationInfo.uid, name);
9392                    return null;
9393                }
9394                try {
9395                    if (DEBUG_MU) {
9396                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9397                                + cpr.launchingApp);
9398                    }
9399                    if (conn != null) {
9400                        conn.waiting = true;
9401                    }
9402                    cpr.wait();
9403                } catch (InterruptedException ex) {
9404                } finally {
9405                    if (conn != null) {
9406                        conn.waiting = false;
9407                    }
9408                }
9409            }
9410        }
9411        return cpr != null ? cpr.newHolder(conn) : null;
9412    }
9413
9414    @Override
9415    public final ContentProviderHolder getContentProvider(
9416            IApplicationThread caller, String name, int userId, boolean stable) {
9417        enforceNotIsolatedCaller("getContentProvider");
9418        if (caller == null) {
9419            String msg = "null IApplicationThread when getting content provider "
9420                    + name;
9421            Slog.w(TAG, msg);
9422            throw new SecurityException(msg);
9423        }
9424        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9425        // with cross-user grant.
9426        return getContentProviderImpl(caller, name, null, stable, userId);
9427    }
9428
9429    public ContentProviderHolder getContentProviderExternal(
9430            String name, int userId, IBinder token) {
9431        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9432            "Do not have permission in call getContentProviderExternal()");
9433        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9434                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9435        return getContentProviderExternalUnchecked(name, token, userId);
9436    }
9437
9438    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9439            IBinder token, int userId) {
9440        return getContentProviderImpl(null, name, token, true, userId);
9441    }
9442
9443    /**
9444     * Drop a content provider from a ProcessRecord's bookkeeping
9445     */
9446    public void removeContentProvider(IBinder connection, boolean stable) {
9447        enforceNotIsolatedCaller("removeContentProvider");
9448        long ident = Binder.clearCallingIdentity();
9449        try {
9450            synchronized (this) {
9451                ContentProviderConnection conn;
9452                try {
9453                    conn = (ContentProviderConnection)connection;
9454                } catch (ClassCastException e) {
9455                    String msg ="removeContentProvider: " + connection
9456                            + " not a ContentProviderConnection";
9457                    Slog.w(TAG, msg);
9458                    throw new IllegalArgumentException(msg);
9459                }
9460                if (conn == null) {
9461                    throw new NullPointerException("connection is null");
9462                }
9463                if (decProviderCountLocked(conn, null, null, stable)) {
9464                    updateOomAdjLocked();
9465                }
9466            }
9467        } finally {
9468            Binder.restoreCallingIdentity(ident);
9469        }
9470    }
9471
9472    public void removeContentProviderExternal(String name, IBinder token) {
9473        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9474            "Do not have permission in call removeContentProviderExternal()");
9475        int userId = UserHandle.getCallingUserId();
9476        long ident = Binder.clearCallingIdentity();
9477        try {
9478            removeContentProviderExternalUnchecked(name, token, userId);
9479        } finally {
9480            Binder.restoreCallingIdentity(ident);
9481        }
9482    }
9483
9484    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9485        synchronized (this) {
9486            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9487            if(cpr == null) {
9488                //remove from mProvidersByClass
9489                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9490                return;
9491            }
9492
9493            //update content provider record entry info
9494            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9495            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9496            if (localCpr.hasExternalProcessHandles()) {
9497                if (localCpr.removeExternalProcessHandleLocked(token)) {
9498                    updateOomAdjLocked();
9499                } else {
9500                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9501                            + " with no external reference for token: "
9502                            + token + ".");
9503                }
9504            } else {
9505                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9506                        + " with no external references.");
9507            }
9508        }
9509    }
9510
9511    public final void publishContentProviders(IApplicationThread caller,
9512            List<ContentProviderHolder> providers) {
9513        if (providers == null) {
9514            return;
9515        }
9516
9517        enforceNotIsolatedCaller("publishContentProviders");
9518        synchronized (this) {
9519            final ProcessRecord r = getRecordForAppLocked(caller);
9520            if (DEBUG_MU)
9521                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9522            if (r == null) {
9523                throw new SecurityException(
9524                        "Unable to find app for caller " + caller
9525                      + " (pid=" + Binder.getCallingPid()
9526                      + ") when publishing content providers");
9527            }
9528
9529            final long origId = Binder.clearCallingIdentity();
9530
9531            final int N = providers.size();
9532            for (int i=0; i<N; i++) {
9533                ContentProviderHolder src = providers.get(i);
9534                if (src == null || src.info == null || src.provider == null) {
9535                    continue;
9536                }
9537                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9538                if (DEBUG_MU)
9539                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9540                if (dst != null) {
9541                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9542                    mProviderMap.putProviderByClass(comp, dst);
9543                    String names[] = dst.info.authority.split(";");
9544                    for (int j = 0; j < names.length; j++) {
9545                        mProviderMap.putProviderByName(names[j], dst);
9546                    }
9547
9548                    int NL = mLaunchingProviders.size();
9549                    int j;
9550                    for (j=0; j<NL; j++) {
9551                        if (mLaunchingProviders.get(j) == dst) {
9552                            mLaunchingProviders.remove(j);
9553                            j--;
9554                            NL--;
9555                        }
9556                    }
9557                    synchronized (dst) {
9558                        dst.provider = src.provider;
9559                        dst.proc = r;
9560                        dst.notifyAll();
9561                    }
9562                    updateOomAdjLocked(r);
9563                }
9564            }
9565
9566            Binder.restoreCallingIdentity(origId);
9567        }
9568    }
9569
9570    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9571        ContentProviderConnection conn;
9572        try {
9573            conn = (ContentProviderConnection)connection;
9574        } catch (ClassCastException e) {
9575            String msg ="refContentProvider: " + connection
9576                    + " not a ContentProviderConnection";
9577            Slog.w(TAG, msg);
9578            throw new IllegalArgumentException(msg);
9579        }
9580        if (conn == null) {
9581            throw new NullPointerException("connection is null");
9582        }
9583
9584        synchronized (this) {
9585            if (stable > 0) {
9586                conn.numStableIncs += stable;
9587            }
9588            stable = conn.stableCount + stable;
9589            if (stable < 0) {
9590                throw new IllegalStateException("stableCount < 0: " + stable);
9591            }
9592
9593            if (unstable > 0) {
9594                conn.numUnstableIncs += unstable;
9595            }
9596            unstable = conn.unstableCount + unstable;
9597            if (unstable < 0) {
9598                throw new IllegalStateException("unstableCount < 0: " + unstable);
9599            }
9600
9601            if ((stable+unstable) <= 0) {
9602                throw new IllegalStateException("ref counts can't go to zero here: stable="
9603                        + stable + " unstable=" + unstable);
9604            }
9605            conn.stableCount = stable;
9606            conn.unstableCount = unstable;
9607            return !conn.dead;
9608        }
9609    }
9610
9611    public void unstableProviderDied(IBinder connection) {
9612        ContentProviderConnection conn;
9613        try {
9614            conn = (ContentProviderConnection)connection;
9615        } catch (ClassCastException e) {
9616            String msg ="refContentProvider: " + connection
9617                    + " not a ContentProviderConnection";
9618            Slog.w(TAG, msg);
9619            throw new IllegalArgumentException(msg);
9620        }
9621        if (conn == null) {
9622            throw new NullPointerException("connection is null");
9623        }
9624
9625        // Safely retrieve the content provider associated with the connection.
9626        IContentProvider provider;
9627        synchronized (this) {
9628            provider = conn.provider.provider;
9629        }
9630
9631        if (provider == null) {
9632            // Um, yeah, we're way ahead of you.
9633            return;
9634        }
9635
9636        // Make sure the caller is being honest with us.
9637        if (provider.asBinder().pingBinder()) {
9638            // Er, no, still looks good to us.
9639            synchronized (this) {
9640                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9641                        + " says " + conn + " died, but we don't agree");
9642                return;
9643            }
9644        }
9645
9646        // Well look at that!  It's dead!
9647        synchronized (this) {
9648            if (conn.provider.provider != provider) {
9649                // But something changed...  good enough.
9650                return;
9651            }
9652
9653            ProcessRecord proc = conn.provider.proc;
9654            if (proc == null || proc.thread == null) {
9655                // Seems like the process is already cleaned up.
9656                return;
9657            }
9658
9659            // As far as we're concerned, this is just like receiving a
9660            // death notification...  just a bit prematurely.
9661            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9662                    + ") early provider death");
9663            final long ident = Binder.clearCallingIdentity();
9664            try {
9665                appDiedLocked(proc);
9666            } finally {
9667                Binder.restoreCallingIdentity(ident);
9668            }
9669        }
9670    }
9671
9672    @Override
9673    public void appNotRespondingViaProvider(IBinder connection) {
9674        enforceCallingPermission(
9675                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9676
9677        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9678        if (conn == null) {
9679            Slog.w(TAG, "ContentProviderConnection is null");
9680            return;
9681        }
9682
9683        final ProcessRecord host = conn.provider.proc;
9684        if (host == null) {
9685            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9686            return;
9687        }
9688
9689        final long token = Binder.clearCallingIdentity();
9690        try {
9691            appNotResponding(host, null, null, false, "ContentProvider not responding");
9692        } finally {
9693            Binder.restoreCallingIdentity(token);
9694        }
9695    }
9696
9697    public final void installSystemProviders() {
9698        List<ProviderInfo> providers;
9699        synchronized (this) {
9700            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9701            providers = generateApplicationProvidersLocked(app);
9702            if (providers != null) {
9703                for (int i=providers.size()-1; i>=0; i--) {
9704                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9705                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9706                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9707                                + ": not system .apk");
9708                        providers.remove(i);
9709                    }
9710                }
9711            }
9712        }
9713        if (providers != null) {
9714            mSystemThread.installSystemProviders(providers);
9715        }
9716
9717        mCoreSettingsObserver = new CoreSettingsObserver(this);
9718
9719        //mUsageStatsService.monitorPackages();
9720    }
9721
9722    /**
9723     * Allows apps to retrieve the MIME type of a URI.
9724     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9725     * users, then it does not need permission to access the ContentProvider.
9726     * Either, it needs cross-user uri grants.
9727     *
9728     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9729     *
9730     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9731     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9732     */
9733    public String getProviderMimeType(Uri uri, int userId) {
9734        enforceNotIsolatedCaller("getProviderMimeType");
9735        final String name = uri.getAuthority();
9736        int callingUid = Binder.getCallingUid();
9737        int callingPid = Binder.getCallingPid();
9738        long ident = 0;
9739        boolean clearedIdentity = false;
9740        userId = unsafeConvertIncomingUser(userId);
9741        if (canClearIdentity(callingPid, callingUid, userId)) {
9742            clearedIdentity = true;
9743            ident = Binder.clearCallingIdentity();
9744        }
9745        ContentProviderHolder holder = null;
9746        try {
9747            holder = getContentProviderExternalUnchecked(name, null, userId);
9748            if (holder != null) {
9749                return holder.provider.getType(uri);
9750            }
9751        } catch (RemoteException e) {
9752            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9753            return null;
9754        } finally {
9755            // We need to clear the identity to call removeContentProviderExternalUnchecked
9756            if (!clearedIdentity) {
9757                ident = Binder.clearCallingIdentity();
9758            }
9759            try {
9760                if (holder != null) {
9761                    removeContentProviderExternalUnchecked(name, null, userId);
9762                }
9763            } finally {
9764                Binder.restoreCallingIdentity(ident);
9765            }
9766        }
9767
9768        return null;
9769    }
9770
9771    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9772        if (UserHandle.getUserId(callingUid) == userId) {
9773            return true;
9774        }
9775        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9776                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9777                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9778                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9779                return true;
9780        }
9781        return false;
9782    }
9783
9784    // =========================================================
9785    // GLOBAL MANAGEMENT
9786    // =========================================================
9787
9788    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9789            boolean isolated, int isolatedUid) {
9790        String proc = customProcess != null ? customProcess : info.processName;
9791        BatteryStatsImpl.Uid.Proc ps = null;
9792        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9793        int uid = info.uid;
9794        if (isolated) {
9795            if (isolatedUid == 0) {
9796                int userId = UserHandle.getUserId(uid);
9797                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9798                while (true) {
9799                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9800                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9801                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9802                    }
9803                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9804                    mNextIsolatedProcessUid++;
9805                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9806                        // No process for this uid, use it.
9807                        break;
9808                    }
9809                    stepsLeft--;
9810                    if (stepsLeft <= 0) {
9811                        return null;
9812                    }
9813                }
9814            } else {
9815                // Special case for startIsolatedProcess (internal only), where
9816                // the uid of the isolated process is specified by the caller.
9817                uid = isolatedUid;
9818            }
9819        }
9820        return new ProcessRecord(stats, info, proc, uid);
9821    }
9822
9823    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9824            String abiOverride) {
9825        ProcessRecord app;
9826        if (!isolated) {
9827            app = getProcessRecordLocked(info.processName, info.uid, true);
9828        } else {
9829            app = null;
9830        }
9831
9832        if (app == null) {
9833            app = newProcessRecordLocked(info, null, isolated, 0);
9834            mProcessNames.put(info.processName, app.uid, app);
9835            if (isolated) {
9836                mIsolatedProcesses.put(app.uid, app);
9837            }
9838            updateLruProcessLocked(app, false, null);
9839            updateOomAdjLocked();
9840        }
9841
9842        // This package really, really can not be stopped.
9843        try {
9844            AppGlobals.getPackageManager().setPackageStoppedState(
9845                    info.packageName, false, UserHandle.getUserId(app.uid));
9846        } catch (RemoteException e) {
9847        } catch (IllegalArgumentException e) {
9848            Slog.w(TAG, "Failed trying to unstop package "
9849                    + info.packageName + ": " + e);
9850        }
9851
9852        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9853                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9854            app.persistent = true;
9855            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9856        }
9857        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9858            mPersistentStartingProcesses.add(app);
9859            startProcessLocked(app, "added application", app.processName, abiOverride,
9860                    null /* entryPoint */, null /* entryPointArgs */);
9861        }
9862
9863        return app;
9864    }
9865
9866    public void unhandledBack() {
9867        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9868                "unhandledBack()");
9869
9870        synchronized(this) {
9871            final long origId = Binder.clearCallingIdentity();
9872            try {
9873                getFocusedStack().unhandledBackLocked();
9874            } finally {
9875                Binder.restoreCallingIdentity(origId);
9876            }
9877        }
9878    }
9879
9880    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9881        enforceNotIsolatedCaller("openContentUri");
9882        final int userId = UserHandle.getCallingUserId();
9883        String name = uri.getAuthority();
9884        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9885        ParcelFileDescriptor pfd = null;
9886        if (cph != null) {
9887            // We record the binder invoker's uid in thread-local storage before
9888            // going to the content provider to open the file.  Later, in the code
9889            // that handles all permissions checks, we look for this uid and use
9890            // that rather than the Activity Manager's own uid.  The effect is that
9891            // we do the check against the caller's permissions even though it looks
9892            // to the content provider like the Activity Manager itself is making
9893            // the request.
9894            Binder token = new Binder();
9895            sCallerIdentity.set(new Identity(
9896                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9897            try {
9898                pfd = cph.provider.openFile(null, uri, "r", null, token);
9899            } catch (FileNotFoundException e) {
9900                // do nothing; pfd will be returned null
9901            } finally {
9902                // Ensure that whatever happens, we clean up the identity state
9903                sCallerIdentity.remove();
9904            }
9905
9906            // We've got the fd now, so we're done with the provider.
9907            removeContentProviderExternalUnchecked(name, null, userId);
9908        } else {
9909            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9910        }
9911        return pfd;
9912    }
9913
9914    // Actually is sleeping or shutting down or whatever else in the future
9915    // is an inactive state.
9916    public boolean isSleepingOrShuttingDown() {
9917        return isSleeping() || mShuttingDown;
9918    }
9919
9920    public boolean isSleeping() {
9921        return mSleeping;
9922    }
9923
9924    void goingToSleep() {
9925        synchronized(this) {
9926            mWentToSleep = true;
9927            goToSleepIfNeededLocked();
9928        }
9929    }
9930
9931    void finishRunningVoiceLocked() {
9932        if (mRunningVoice) {
9933            mRunningVoice = false;
9934            goToSleepIfNeededLocked();
9935        }
9936    }
9937
9938    void goToSleepIfNeededLocked() {
9939        if (mWentToSleep && !mRunningVoice) {
9940            if (!mSleeping) {
9941                mSleeping = true;
9942                mStackSupervisor.goingToSleepLocked();
9943
9944                // Initialize the wake times of all processes.
9945                checkExcessivePowerUsageLocked(false);
9946                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9947                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9948                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9949            }
9950        }
9951    }
9952
9953    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9954        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9955            // Never persist the home stack.
9956            return;
9957        }
9958        mTaskPersister.wakeup(task, flush);
9959    }
9960
9961    @Override
9962    public boolean shutdown(int timeout) {
9963        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9964                != PackageManager.PERMISSION_GRANTED) {
9965            throw new SecurityException("Requires permission "
9966                    + android.Manifest.permission.SHUTDOWN);
9967        }
9968
9969        boolean timedout = false;
9970
9971        synchronized(this) {
9972            mShuttingDown = true;
9973            updateEventDispatchingLocked();
9974            timedout = mStackSupervisor.shutdownLocked(timeout);
9975        }
9976
9977        mAppOpsService.shutdown();
9978        if (mUsageStatsService != null) {
9979            mUsageStatsService.prepareShutdown();
9980        }
9981        mBatteryStatsService.shutdown();
9982        synchronized (this) {
9983            mProcessStats.shutdownLocked();
9984        }
9985        notifyTaskPersisterLocked(null, true);
9986
9987        return timedout;
9988    }
9989
9990    public final void activitySlept(IBinder token) {
9991        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9992
9993        final long origId = Binder.clearCallingIdentity();
9994
9995        synchronized (this) {
9996            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9997            if (r != null) {
9998                mStackSupervisor.activitySleptLocked(r);
9999            }
10000        }
10001
10002        Binder.restoreCallingIdentity(origId);
10003    }
10004
10005    private String lockScreenShownToString() {
10006        switch (mLockScreenShown) {
10007            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10008            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10009            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10010            default: return "Unknown=" + mLockScreenShown;
10011        }
10012    }
10013
10014    void logLockScreen(String msg) {
10015        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10016                " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" +
10017                mWentToSleep + " mSleeping=" + mSleeping);
10018    }
10019
10020    void comeOutOfSleepIfNeededLocked() {
10021        if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) {
10022            if (mSleeping) {
10023                mSleeping = false;
10024                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10025            }
10026        }
10027    }
10028
10029    void wakingUp() {
10030        synchronized(this) {
10031            mWentToSleep = false;
10032            comeOutOfSleepIfNeededLocked();
10033        }
10034    }
10035
10036    void startRunningVoiceLocked() {
10037        if (!mRunningVoice) {
10038            mRunningVoice = true;
10039            comeOutOfSleepIfNeededLocked();
10040        }
10041    }
10042
10043    private void updateEventDispatchingLocked() {
10044        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10045    }
10046
10047    public void setLockScreenShown(boolean shown) {
10048        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10049                != PackageManager.PERMISSION_GRANTED) {
10050            throw new SecurityException("Requires permission "
10051                    + android.Manifest.permission.DEVICE_POWER);
10052        }
10053
10054        synchronized(this) {
10055            long ident = Binder.clearCallingIdentity();
10056            try {
10057                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10058                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10059                comeOutOfSleepIfNeededLocked();
10060            } finally {
10061                Binder.restoreCallingIdentity(ident);
10062            }
10063        }
10064    }
10065
10066    @Override
10067    public void stopAppSwitches() {
10068        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10069                != PackageManager.PERMISSION_GRANTED) {
10070            throw new SecurityException("Requires permission "
10071                    + android.Manifest.permission.STOP_APP_SWITCHES);
10072        }
10073
10074        synchronized(this) {
10075            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10076                    + APP_SWITCH_DELAY_TIME;
10077            mDidAppSwitch = false;
10078            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10079            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10080            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10081        }
10082    }
10083
10084    public void resumeAppSwitches() {
10085        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10086                != PackageManager.PERMISSION_GRANTED) {
10087            throw new SecurityException("Requires permission "
10088                    + android.Manifest.permission.STOP_APP_SWITCHES);
10089        }
10090
10091        synchronized(this) {
10092            // Note that we don't execute any pending app switches... we will
10093            // let those wait until either the timeout, or the next start
10094            // activity request.
10095            mAppSwitchesAllowedTime = 0;
10096        }
10097    }
10098
10099    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10100            int callingPid, int callingUid, String name) {
10101        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10102            return true;
10103        }
10104
10105        int perm = checkComponentPermission(
10106                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10107                sourceUid, -1, true);
10108        if (perm == PackageManager.PERMISSION_GRANTED) {
10109            return true;
10110        }
10111
10112        // If the actual IPC caller is different from the logical source, then
10113        // also see if they are allowed to control app switches.
10114        if (callingUid != -1 && callingUid != sourceUid) {
10115            perm = checkComponentPermission(
10116                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10117                    callingUid, -1, true);
10118            if (perm == PackageManager.PERMISSION_GRANTED) {
10119                return true;
10120            }
10121        }
10122
10123        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10124        return false;
10125    }
10126
10127    public void setDebugApp(String packageName, boolean waitForDebugger,
10128            boolean persistent) {
10129        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10130                "setDebugApp()");
10131
10132        long ident = Binder.clearCallingIdentity();
10133        try {
10134            // Note that this is not really thread safe if there are multiple
10135            // callers into it at the same time, but that's not a situation we
10136            // care about.
10137            if (persistent) {
10138                final ContentResolver resolver = mContext.getContentResolver();
10139                Settings.Global.putString(
10140                    resolver, Settings.Global.DEBUG_APP,
10141                    packageName);
10142                Settings.Global.putInt(
10143                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10144                    waitForDebugger ? 1 : 0);
10145            }
10146
10147            synchronized (this) {
10148                if (!persistent) {
10149                    mOrigDebugApp = mDebugApp;
10150                    mOrigWaitForDebugger = mWaitForDebugger;
10151                }
10152                mDebugApp = packageName;
10153                mWaitForDebugger = waitForDebugger;
10154                mDebugTransient = !persistent;
10155                if (packageName != null) {
10156                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10157                            false, UserHandle.USER_ALL, "set debug app");
10158                }
10159            }
10160        } finally {
10161            Binder.restoreCallingIdentity(ident);
10162        }
10163    }
10164
10165    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10166        synchronized (this) {
10167            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10168            if (!isDebuggable) {
10169                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10170                    throw new SecurityException("Process not debuggable: " + app.packageName);
10171                }
10172            }
10173
10174            mOpenGlTraceApp = processName;
10175        }
10176    }
10177
10178    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10179        synchronized (this) {
10180            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10181            if (!isDebuggable) {
10182                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10183                    throw new SecurityException("Process not debuggable: " + app.packageName);
10184                }
10185            }
10186            mProfileApp = processName;
10187            mProfileFile = profilerInfo.profileFile;
10188            if (mProfileFd != null) {
10189                try {
10190                    mProfileFd.close();
10191                } catch (IOException e) {
10192                }
10193                mProfileFd = null;
10194            }
10195            mProfileFd = profilerInfo.profileFd;
10196            mSamplingInterval = profilerInfo.samplingInterval;
10197            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10198            mProfileType = 0;
10199        }
10200    }
10201
10202    @Override
10203    public void setAlwaysFinish(boolean enabled) {
10204        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10205                "setAlwaysFinish()");
10206
10207        Settings.Global.putInt(
10208                mContext.getContentResolver(),
10209                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10210
10211        synchronized (this) {
10212            mAlwaysFinishActivities = enabled;
10213        }
10214    }
10215
10216    @Override
10217    public void setActivityController(IActivityController controller) {
10218        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10219                "setActivityController()");
10220        synchronized (this) {
10221            mController = controller;
10222            Watchdog.getInstance().setActivityController(controller);
10223        }
10224    }
10225
10226    @Override
10227    public void setUserIsMonkey(boolean userIsMonkey) {
10228        synchronized (this) {
10229            synchronized (mPidsSelfLocked) {
10230                final int callingPid = Binder.getCallingPid();
10231                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10232                if (precessRecord == null) {
10233                    throw new SecurityException("Unknown process: " + callingPid);
10234                }
10235                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10236                    throw new SecurityException("Only an instrumentation process "
10237                            + "with a UiAutomation can call setUserIsMonkey");
10238                }
10239            }
10240            mUserIsMonkey = userIsMonkey;
10241        }
10242    }
10243
10244    @Override
10245    public boolean isUserAMonkey() {
10246        synchronized (this) {
10247            // If there is a controller also implies the user is a monkey.
10248            return (mUserIsMonkey || mController != null);
10249        }
10250    }
10251
10252    public void requestBugReport() {
10253        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10254        SystemProperties.set("ctl.start", "bugreport");
10255    }
10256
10257    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10258        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10259    }
10260
10261    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10262        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10263            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10264        }
10265        return KEY_DISPATCHING_TIMEOUT;
10266    }
10267
10268    @Override
10269    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10270        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10271                != PackageManager.PERMISSION_GRANTED) {
10272            throw new SecurityException("Requires permission "
10273                    + android.Manifest.permission.FILTER_EVENTS);
10274        }
10275        ProcessRecord proc;
10276        long timeout;
10277        synchronized (this) {
10278            synchronized (mPidsSelfLocked) {
10279                proc = mPidsSelfLocked.get(pid);
10280            }
10281            timeout = getInputDispatchingTimeoutLocked(proc);
10282        }
10283
10284        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10285            return -1;
10286        }
10287
10288        return timeout;
10289    }
10290
10291    /**
10292     * Handle input dispatching timeouts.
10293     * Returns whether input dispatching should be aborted or not.
10294     */
10295    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10296            final ActivityRecord activity, final ActivityRecord parent,
10297            final boolean aboveSystem, String reason) {
10298        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10299                != PackageManager.PERMISSION_GRANTED) {
10300            throw new SecurityException("Requires permission "
10301                    + android.Manifest.permission.FILTER_EVENTS);
10302        }
10303
10304        final String annotation;
10305        if (reason == null) {
10306            annotation = "Input dispatching timed out";
10307        } else {
10308            annotation = "Input dispatching timed out (" + reason + ")";
10309        }
10310
10311        if (proc != null) {
10312            synchronized (this) {
10313                if (proc.debugging) {
10314                    return false;
10315                }
10316
10317                if (mDidDexOpt) {
10318                    // Give more time since we were dexopting.
10319                    mDidDexOpt = false;
10320                    return false;
10321                }
10322
10323                if (proc.instrumentationClass != null) {
10324                    Bundle info = new Bundle();
10325                    info.putString("shortMsg", "keyDispatchingTimedOut");
10326                    info.putString("longMsg", annotation);
10327                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10328                    return true;
10329                }
10330            }
10331            mHandler.post(new Runnable() {
10332                @Override
10333                public void run() {
10334                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10335                }
10336            });
10337        }
10338
10339        return true;
10340    }
10341
10342    public Bundle getAssistContextExtras(int requestType) {
10343        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10344                UserHandle.getCallingUserId());
10345        if (pae == null) {
10346            return null;
10347        }
10348        synchronized (pae) {
10349            while (!pae.haveResult) {
10350                try {
10351                    pae.wait();
10352                } catch (InterruptedException e) {
10353                }
10354            }
10355            if (pae.result != null) {
10356                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10357            }
10358        }
10359        synchronized (this) {
10360            mPendingAssistExtras.remove(pae);
10361            mHandler.removeCallbacks(pae);
10362        }
10363        return pae.extras;
10364    }
10365
10366    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10367            int userHandle) {
10368        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10369                "getAssistContextExtras()");
10370        PendingAssistExtras pae;
10371        Bundle extras = new Bundle();
10372        synchronized (this) {
10373            ActivityRecord activity = getFocusedStack().mResumedActivity;
10374            if (activity == null) {
10375                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10376                return null;
10377            }
10378            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10379            if (activity.app == null || activity.app.thread == null) {
10380                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10381                return null;
10382            }
10383            if (activity.app.pid == Binder.getCallingPid()) {
10384                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10385                return null;
10386            }
10387            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10388            try {
10389                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10390                        requestType);
10391                mPendingAssistExtras.add(pae);
10392                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10393            } catch (RemoteException e) {
10394                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10395                return null;
10396            }
10397            return pae;
10398        }
10399    }
10400
10401    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10402        PendingAssistExtras pae = (PendingAssistExtras)token;
10403        synchronized (pae) {
10404            pae.result = extras;
10405            pae.haveResult = true;
10406            pae.notifyAll();
10407            if (pae.intent == null) {
10408                // Caller is just waiting for the result.
10409                return;
10410            }
10411        }
10412
10413        // We are now ready to launch the assist activity.
10414        synchronized (this) {
10415            boolean exists = mPendingAssistExtras.remove(pae);
10416            mHandler.removeCallbacks(pae);
10417            if (!exists) {
10418                // Timed out.
10419                return;
10420            }
10421        }
10422        pae.intent.replaceExtras(extras);
10423        if (pae.hint != null) {
10424            pae.intent.putExtra(pae.hint, true);
10425        }
10426        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10427                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10428                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10429        closeSystemDialogs("assist");
10430        try {
10431            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10432        } catch (ActivityNotFoundException e) {
10433            Slog.w(TAG, "No activity to handle assist action.", e);
10434        }
10435    }
10436
10437    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10438        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10439    }
10440
10441    public void registerProcessObserver(IProcessObserver observer) {
10442        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10443                "registerProcessObserver()");
10444        synchronized (this) {
10445            mProcessObservers.register(observer);
10446        }
10447    }
10448
10449    @Override
10450    public void unregisterProcessObserver(IProcessObserver observer) {
10451        synchronized (this) {
10452            mProcessObservers.unregister(observer);
10453        }
10454    }
10455
10456    @Override
10457    public boolean convertFromTranslucent(IBinder token) {
10458        final long origId = Binder.clearCallingIdentity();
10459        try {
10460            synchronized (this) {
10461                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10462                if (r == null) {
10463                    return false;
10464                }
10465                final boolean translucentChanged = r.changeWindowTranslucency(true);
10466                if (translucentChanged) {
10467                    r.task.stack.releaseBackgroundResources();
10468                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10469                }
10470                mWindowManager.setAppFullscreen(token, true);
10471                return translucentChanged;
10472            }
10473        } finally {
10474            Binder.restoreCallingIdentity(origId);
10475        }
10476    }
10477
10478    @Override
10479    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10480        final long origId = Binder.clearCallingIdentity();
10481        try {
10482            synchronized (this) {
10483                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10484                if (r == null) {
10485                    return false;
10486                }
10487                int index = r.task.mActivities.lastIndexOf(r);
10488                if (index > 0) {
10489                    ActivityRecord under = r.task.mActivities.get(index - 1);
10490                    under.returningOptions = options;
10491                }
10492                final boolean translucentChanged = r.changeWindowTranslucency(false);
10493                if (translucentChanged) {
10494                    r.task.stack.convertToTranslucent(r);
10495                }
10496                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10497                mWindowManager.setAppFullscreen(token, false);
10498                return translucentChanged;
10499            }
10500        } finally {
10501            Binder.restoreCallingIdentity(origId);
10502        }
10503    }
10504
10505    @Override
10506    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10507        final long origId = Binder.clearCallingIdentity();
10508        try {
10509            synchronized (this) {
10510                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10511                if (r != null) {
10512                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10513                }
10514            }
10515            return false;
10516        } finally {
10517            Binder.restoreCallingIdentity(origId);
10518        }
10519    }
10520
10521    @Override
10522    public boolean isBackgroundVisibleBehind(IBinder token) {
10523        final long origId = Binder.clearCallingIdentity();
10524        try {
10525            synchronized (this) {
10526                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10527                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10528                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10529                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10530                return visible;
10531            }
10532        } finally {
10533            Binder.restoreCallingIdentity(origId);
10534        }
10535    }
10536
10537    @Override
10538    public ActivityOptions getActivityOptions(IBinder token) {
10539        final long origId = Binder.clearCallingIdentity();
10540        try {
10541            synchronized (this) {
10542                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10543                if (r != null) {
10544                    final ActivityOptions activityOptions = r.pendingOptions;
10545                    r.pendingOptions = null;
10546                    return activityOptions;
10547                }
10548                return null;
10549            }
10550        } finally {
10551            Binder.restoreCallingIdentity(origId);
10552        }
10553    }
10554
10555    @Override
10556    public void setImmersive(IBinder token, boolean immersive) {
10557        synchronized(this) {
10558            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10559            if (r == null) {
10560                throw new IllegalArgumentException();
10561            }
10562            r.immersive = immersive;
10563
10564            // update associated state if we're frontmost
10565            if (r == mFocusedActivity) {
10566                if (DEBUG_IMMERSIVE) {
10567                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10568                }
10569                applyUpdateLockStateLocked(r);
10570            }
10571        }
10572    }
10573
10574    @Override
10575    public boolean isImmersive(IBinder token) {
10576        synchronized (this) {
10577            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10578            if (r == null) {
10579                throw new IllegalArgumentException();
10580            }
10581            return r.immersive;
10582        }
10583    }
10584
10585    public boolean isTopActivityImmersive() {
10586        enforceNotIsolatedCaller("startActivity");
10587        synchronized (this) {
10588            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10589            return (r != null) ? r.immersive : false;
10590        }
10591    }
10592
10593    @Override
10594    public boolean isTopOfTask(IBinder token) {
10595        synchronized (this) {
10596            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10597            if (r == null) {
10598                throw new IllegalArgumentException();
10599            }
10600            return r.task.getTopActivity() == r;
10601        }
10602    }
10603
10604    public final void enterSafeMode() {
10605        synchronized(this) {
10606            // It only makes sense to do this before the system is ready
10607            // and started launching other packages.
10608            if (!mSystemReady) {
10609                try {
10610                    AppGlobals.getPackageManager().enterSafeMode();
10611                } catch (RemoteException e) {
10612                }
10613            }
10614
10615            mSafeMode = true;
10616        }
10617    }
10618
10619    public final void showSafeModeOverlay() {
10620        View v = LayoutInflater.from(mContext).inflate(
10621                com.android.internal.R.layout.safe_mode, null);
10622        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10623        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10624        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10625        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10626        lp.gravity = Gravity.BOTTOM | Gravity.START;
10627        lp.format = v.getBackground().getOpacity();
10628        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10629                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10630        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10631        ((WindowManager)mContext.getSystemService(
10632                Context.WINDOW_SERVICE)).addView(v, lp);
10633    }
10634
10635    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10636        if (!(sender instanceof PendingIntentRecord)) {
10637            return;
10638        }
10639        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10640        synchronized (stats) {
10641            if (mBatteryStatsService.isOnBattery()) {
10642                mBatteryStatsService.enforceCallingPermission();
10643                PendingIntentRecord rec = (PendingIntentRecord)sender;
10644                int MY_UID = Binder.getCallingUid();
10645                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10646                BatteryStatsImpl.Uid.Pkg pkg =
10647                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10648                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10649                pkg.incWakeupsLocked();
10650            }
10651        }
10652    }
10653
10654    public boolean killPids(int[] pids, String pReason, boolean secure) {
10655        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10656            throw new SecurityException("killPids only available to the system");
10657        }
10658        String reason = (pReason == null) ? "Unknown" : pReason;
10659        // XXX Note: don't acquire main activity lock here, because the window
10660        // manager calls in with its locks held.
10661
10662        boolean killed = false;
10663        synchronized (mPidsSelfLocked) {
10664            int[] types = new int[pids.length];
10665            int worstType = 0;
10666            for (int i=0; i<pids.length; i++) {
10667                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10668                if (proc != null) {
10669                    int type = proc.setAdj;
10670                    types[i] = type;
10671                    if (type > worstType) {
10672                        worstType = type;
10673                    }
10674                }
10675            }
10676
10677            // If the worst oom_adj is somewhere in the cached proc LRU range,
10678            // then constrain it so we will kill all cached procs.
10679            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10680                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10681                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10682            }
10683
10684            // If this is not a secure call, don't let it kill processes that
10685            // are important.
10686            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10687                worstType = ProcessList.SERVICE_ADJ;
10688            }
10689
10690            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10691            for (int i=0; i<pids.length; i++) {
10692                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10693                if (proc == null) {
10694                    continue;
10695                }
10696                int adj = proc.setAdj;
10697                if (adj >= worstType && !proc.killedByAm) {
10698                    proc.kill(reason, true);
10699                    killed = true;
10700                }
10701            }
10702        }
10703        return killed;
10704    }
10705
10706    @Override
10707    public void killUid(int uid, String reason) {
10708        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10709            throw new SecurityException("killUid only available to the system");
10710        }
10711        synchronized (this) {
10712            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10713                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10714                    reason != null ? reason : "kill uid");
10715        }
10716    }
10717
10718    @Override
10719    public boolean killProcessesBelowForeground(String reason) {
10720        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10721            throw new SecurityException("killProcessesBelowForeground() only available to system");
10722        }
10723
10724        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10725    }
10726
10727    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10728        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10729            throw new SecurityException("killProcessesBelowAdj() only available to system");
10730        }
10731
10732        boolean killed = false;
10733        synchronized (mPidsSelfLocked) {
10734            final int size = mPidsSelfLocked.size();
10735            for (int i = 0; i < size; i++) {
10736                final int pid = mPidsSelfLocked.keyAt(i);
10737                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10738                if (proc == null) continue;
10739
10740                final int adj = proc.setAdj;
10741                if (adj > belowAdj && !proc.killedByAm) {
10742                    proc.kill(reason, true);
10743                    killed = true;
10744                }
10745            }
10746        }
10747        return killed;
10748    }
10749
10750    @Override
10751    public void hang(final IBinder who, boolean allowRestart) {
10752        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10753                != PackageManager.PERMISSION_GRANTED) {
10754            throw new SecurityException("Requires permission "
10755                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10756        }
10757
10758        final IBinder.DeathRecipient death = new DeathRecipient() {
10759            @Override
10760            public void binderDied() {
10761                synchronized (this) {
10762                    notifyAll();
10763                }
10764            }
10765        };
10766
10767        try {
10768            who.linkToDeath(death, 0);
10769        } catch (RemoteException e) {
10770            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10771            return;
10772        }
10773
10774        synchronized (this) {
10775            Watchdog.getInstance().setAllowRestart(allowRestart);
10776            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10777            synchronized (death) {
10778                while (who.isBinderAlive()) {
10779                    try {
10780                        death.wait();
10781                    } catch (InterruptedException e) {
10782                    }
10783                }
10784            }
10785            Watchdog.getInstance().setAllowRestart(true);
10786        }
10787    }
10788
10789    @Override
10790    public void restart() {
10791        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10792                != PackageManager.PERMISSION_GRANTED) {
10793            throw new SecurityException("Requires permission "
10794                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10795        }
10796
10797        Log.i(TAG, "Sending shutdown broadcast...");
10798
10799        BroadcastReceiver br = new BroadcastReceiver() {
10800            @Override public void onReceive(Context context, Intent intent) {
10801                // Now the broadcast is done, finish up the low-level shutdown.
10802                Log.i(TAG, "Shutting down activity manager...");
10803                shutdown(10000);
10804                Log.i(TAG, "Shutdown complete, restarting!");
10805                Process.killProcess(Process.myPid());
10806                System.exit(10);
10807            }
10808        };
10809
10810        // First send the high-level shut down broadcast.
10811        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10812        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10813        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10814        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10815        mContext.sendOrderedBroadcastAsUser(intent,
10816                UserHandle.ALL, null, br, mHandler, 0, null, null);
10817        */
10818        br.onReceive(mContext, intent);
10819    }
10820
10821    private long getLowRamTimeSinceIdle(long now) {
10822        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10823    }
10824
10825    @Override
10826    public void performIdleMaintenance() {
10827        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10828                != PackageManager.PERMISSION_GRANTED) {
10829            throw new SecurityException("Requires permission "
10830                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10831        }
10832
10833        synchronized (this) {
10834            final long now = SystemClock.uptimeMillis();
10835            final long timeSinceLastIdle = now - mLastIdleTime;
10836            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10837            mLastIdleTime = now;
10838            mLowRamTimeSinceLastIdle = 0;
10839            if (mLowRamStartTime != 0) {
10840                mLowRamStartTime = now;
10841            }
10842
10843            StringBuilder sb = new StringBuilder(128);
10844            sb.append("Idle maintenance over ");
10845            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10846            sb.append(" low RAM for ");
10847            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10848            Slog.i(TAG, sb.toString());
10849
10850            // If at least 1/3 of our time since the last idle period has been spent
10851            // with RAM low, then we want to kill processes.
10852            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10853
10854            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10855                ProcessRecord proc = mLruProcesses.get(i);
10856                if (proc.notCachedSinceIdle) {
10857                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10858                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10859                        if (doKilling && proc.initialIdlePss != 0
10860                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10861                            proc.kill("idle maint (pss " + proc.lastPss
10862                                    + " from " + proc.initialIdlePss + ")", true);
10863                        }
10864                    }
10865                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10866                    proc.notCachedSinceIdle = true;
10867                    proc.initialIdlePss = 0;
10868                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10869                            isSleeping(), now);
10870                }
10871            }
10872
10873            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10874            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10875        }
10876    }
10877
10878    private void retrieveSettings() {
10879        final ContentResolver resolver = mContext.getContentResolver();
10880        String debugApp = Settings.Global.getString(
10881            resolver, Settings.Global.DEBUG_APP);
10882        boolean waitForDebugger = Settings.Global.getInt(
10883            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10884        boolean alwaysFinishActivities = Settings.Global.getInt(
10885            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10886        boolean forceRtl = Settings.Global.getInt(
10887                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10888        // Transfer any global setting for forcing RTL layout, into a System Property
10889        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10890
10891        Configuration configuration = new Configuration();
10892        Settings.System.getConfiguration(resolver, configuration);
10893        if (forceRtl) {
10894            // This will take care of setting the correct layout direction flags
10895            configuration.setLayoutDirection(configuration.locale);
10896        }
10897
10898        synchronized (this) {
10899            mDebugApp = mOrigDebugApp = debugApp;
10900            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10901            mAlwaysFinishActivities = alwaysFinishActivities;
10902            // This happens before any activities are started, so we can
10903            // change mConfiguration in-place.
10904            updateConfigurationLocked(configuration, null, false, true);
10905            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10906        }
10907    }
10908
10909    /** Loads resources after the current configuration has been set. */
10910    private void loadResourcesOnSystemReady() {
10911        final Resources res = mContext.getResources();
10912        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10913        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10914        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10915    }
10916
10917    public boolean testIsSystemReady() {
10918        // no need to synchronize(this) just to read & return the value
10919        return mSystemReady;
10920    }
10921
10922    private static File getCalledPreBootReceiversFile() {
10923        File dataDir = Environment.getDataDirectory();
10924        File systemDir = new File(dataDir, "system");
10925        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10926        return fname;
10927    }
10928
10929    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10930        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10931        File file = getCalledPreBootReceiversFile();
10932        FileInputStream fis = null;
10933        try {
10934            fis = new FileInputStream(file);
10935            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10936            int fvers = dis.readInt();
10937            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10938                String vers = dis.readUTF();
10939                String codename = dis.readUTF();
10940                String build = dis.readUTF();
10941                if (android.os.Build.VERSION.RELEASE.equals(vers)
10942                        && android.os.Build.VERSION.CODENAME.equals(codename)
10943                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10944                    int num = dis.readInt();
10945                    while (num > 0) {
10946                        num--;
10947                        String pkg = dis.readUTF();
10948                        String cls = dis.readUTF();
10949                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10950                    }
10951                }
10952            }
10953        } catch (FileNotFoundException e) {
10954        } catch (IOException e) {
10955            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10956        } finally {
10957            if (fis != null) {
10958                try {
10959                    fis.close();
10960                } catch (IOException e) {
10961                }
10962            }
10963        }
10964        return lastDoneReceivers;
10965    }
10966
10967    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10968        File file = getCalledPreBootReceiversFile();
10969        FileOutputStream fos = null;
10970        DataOutputStream dos = null;
10971        try {
10972            fos = new FileOutputStream(file);
10973            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10974            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10975            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10976            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10977            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10978            dos.writeInt(list.size());
10979            for (int i=0; i<list.size(); i++) {
10980                dos.writeUTF(list.get(i).getPackageName());
10981                dos.writeUTF(list.get(i).getClassName());
10982            }
10983        } catch (IOException e) {
10984            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10985            file.delete();
10986        } finally {
10987            FileUtils.sync(fos);
10988            if (dos != null) {
10989                try {
10990                    dos.close();
10991                } catch (IOException e) {
10992                    // TODO Auto-generated catch block
10993                    e.printStackTrace();
10994                }
10995            }
10996        }
10997    }
10998
10999    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11000            ArrayList<ComponentName> doneReceivers, int userId) {
11001        boolean waitingUpdate = false;
11002        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11003        List<ResolveInfo> ris = null;
11004        try {
11005            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11006                    intent, null, 0, userId);
11007        } catch (RemoteException e) {
11008        }
11009        if (ris != null) {
11010            for (int i=ris.size()-1; i>=0; i--) {
11011                if ((ris.get(i).activityInfo.applicationInfo.flags
11012                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11013                    ris.remove(i);
11014                }
11015            }
11016            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11017
11018            // For User 0, load the version number. When delivering to a new user, deliver
11019            // to all receivers.
11020            if (userId == UserHandle.USER_OWNER) {
11021                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11022                for (int i=0; i<ris.size(); i++) {
11023                    ActivityInfo ai = ris.get(i).activityInfo;
11024                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11025                    if (lastDoneReceivers.contains(comp)) {
11026                        // We already did the pre boot receiver for this app with the current
11027                        // platform version, so don't do it again...
11028                        ris.remove(i);
11029                        i--;
11030                        // ...however, do keep it as one that has been done, so we don't
11031                        // forget about it when rewriting the file of last done receivers.
11032                        doneReceivers.add(comp);
11033                    }
11034                }
11035            }
11036
11037            // If primary user, send broadcast to all available users, else just to userId
11038            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11039                    : new int[] { userId };
11040            for (int i = 0; i < ris.size(); i++) {
11041                ActivityInfo ai = ris.get(i).activityInfo;
11042                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11043                doneReceivers.add(comp);
11044                intent.setComponent(comp);
11045                for (int j=0; j<users.length; j++) {
11046                    IIntentReceiver finisher = null;
11047                    // On last receiver and user, set up a completion callback
11048                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11049                        finisher = new IIntentReceiver.Stub() {
11050                            public void performReceive(Intent intent, int resultCode,
11051                                    String data, Bundle extras, boolean ordered,
11052                                    boolean sticky, int sendingUser) {
11053                                // The raw IIntentReceiver interface is called
11054                                // with the AM lock held, so redispatch to
11055                                // execute our code without the lock.
11056                                mHandler.post(onFinishCallback);
11057                            }
11058                        };
11059                    }
11060                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11061                            + " for user " + users[j]);
11062                    broadcastIntentLocked(null, null, intent, null, finisher,
11063                            0, null, null, null, AppOpsManager.OP_NONE,
11064                            true, false, MY_PID, Process.SYSTEM_UID,
11065                            users[j]);
11066                    if (finisher != null) {
11067                        waitingUpdate = true;
11068                    }
11069                }
11070            }
11071        }
11072
11073        return waitingUpdate;
11074    }
11075
11076    public void systemReady(final Runnable goingCallback) {
11077        synchronized(this) {
11078            if (mSystemReady) {
11079                // If we're done calling all the receivers, run the next "boot phase" passed in
11080                // by the SystemServer
11081                if (goingCallback != null) {
11082                    goingCallback.run();
11083                }
11084                return;
11085            }
11086
11087            // Make sure we have the current profile info, since it is needed for
11088            // security checks.
11089            updateCurrentProfileIdsLocked();
11090
11091            if (mRecentTasks == null) {
11092                mRecentTasks = mTaskPersister.restoreTasksLocked();
11093                if (!mRecentTasks.isEmpty()) {
11094                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11095                }
11096                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11097                mTaskPersister.startPersisting();
11098            }
11099
11100            // Check to see if there are any update receivers to run.
11101            if (!mDidUpdate) {
11102                if (mWaitingUpdate) {
11103                    return;
11104                }
11105                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11106                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11107                    public void run() {
11108                        synchronized (ActivityManagerService.this) {
11109                            mDidUpdate = true;
11110                        }
11111                        writeLastDonePreBootReceivers(doneReceivers);
11112                        showBootMessage(mContext.getText(
11113                                R.string.android_upgrading_complete),
11114                                false);
11115                        systemReady(goingCallback);
11116                    }
11117                }, doneReceivers, UserHandle.USER_OWNER);
11118
11119                if (mWaitingUpdate) {
11120                    return;
11121                }
11122                mDidUpdate = true;
11123            }
11124
11125            mAppOpsService.systemReady();
11126            mSystemReady = true;
11127        }
11128
11129        ArrayList<ProcessRecord> procsToKill = null;
11130        synchronized(mPidsSelfLocked) {
11131            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11132                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11133                if (!isAllowedWhileBooting(proc.info)){
11134                    if (procsToKill == null) {
11135                        procsToKill = new ArrayList<ProcessRecord>();
11136                    }
11137                    procsToKill.add(proc);
11138                }
11139            }
11140        }
11141
11142        synchronized(this) {
11143            if (procsToKill != null) {
11144                for (int i=procsToKill.size()-1; i>=0; i--) {
11145                    ProcessRecord proc = procsToKill.get(i);
11146                    Slog.i(TAG, "Removing system update proc: " + proc);
11147                    removeProcessLocked(proc, true, false, "system update done");
11148                }
11149            }
11150
11151            // Now that we have cleaned up any update processes, we
11152            // are ready to start launching real processes and know that
11153            // we won't trample on them any more.
11154            mProcessesReady = true;
11155        }
11156
11157        Slog.i(TAG, "System now ready");
11158        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11159            SystemClock.uptimeMillis());
11160
11161        synchronized(this) {
11162            // Make sure we have no pre-ready processes sitting around.
11163
11164            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11165                ResolveInfo ri = mContext.getPackageManager()
11166                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11167                                STOCK_PM_FLAGS);
11168                CharSequence errorMsg = null;
11169                if (ri != null) {
11170                    ActivityInfo ai = ri.activityInfo;
11171                    ApplicationInfo app = ai.applicationInfo;
11172                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11173                        mTopAction = Intent.ACTION_FACTORY_TEST;
11174                        mTopData = null;
11175                        mTopComponent = new ComponentName(app.packageName,
11176                                ai.name);
11177                    } else {
11178                        errorMsg = mContext.getResources().getText(
11179                                com.android.internal.R.string.factorytest_not_system);
11180                    }
11181                } else {
11182                    errorMsg = mContext.getResources().getText(
11183                            com.android.internal.R.string.factorytest_no_action);
11184                }
11185                if (errorMsg != null) {
11186                    mTopAction = null;
11187                    mTopData = null;
11188                    mTopComponent = null;
11189                    Message msg = Message.obtain();
11190                    msg.what = SHOW_FACTORY_ERROR_MSG;
11191                    msg.getData().putCharSequence("msg", errorMsg);
11192                    mHandler.sendMessage(msg);
11193                }
11194            }
11195        }
11196
11197        retrieveSettings();
11198        loadResourcesOnSystemReady();
11199
11200        synchronized (this) {
11201            readGrantedUriPermissionsLocked();
11202        }
11203
11204        if (goingCallback != null) goingCallback.run();
11205
11206        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11207                Integer.toString(mCurrentUserId), mCurrentUserId);
11208        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11209                Integer.toString(mCurrentUserId), mCurrentUserId);
11210        mSystemServiceManager.startUser(mCurrentUserId);
11211
11212        synchronized (this) {
11213            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11214                try {
11215                    List apps = AppGlobals.getPackageManager().
11216                        getPersistentApplications(STOCK_PM_FLAGS);
11217                    if (apps != null) {
11218                        int N = apps.size();
11219                        int i;
11220                        for (i=0; i<N; i++) {
11221                            ApplicationInfo info
11222                                = (ApplicationInfo)apps.get(i);
11223                            if (info != null &&
11224                                    !info.packageName.equals("android")) {
11225                                addAppLocked(info, false, null /* ABI override */);
11226                            }
11227                        }
11228                    }
11229                } catch (RemoteException ex) {
11230                    // pm is in same process, this will never happen.
11231                }
11232            }
11233
11234            // Start up initial activity.
11235            mBooting = true;
11236            startHomeActivityLocked(mCurrentUserId);
11237
11238            try {
11239                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11240                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11241                            + " data partition or your device will be unstable.");
11242                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11243                }
11244            } catch (RemoteException e) {
11245            }
11246
11247            if (!Build.isFingerprintConsistent()) {
11248                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11249                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11250            }
11251
11252            long ident = Binder.clearCallingIdentity();
11253            try {
11254                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11255                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11256                        | Intent.FLAG_RECEIVER_FOREGROUND);
11257                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11258                broadcastIntentLocked(null, null, intent,
11259                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11260                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11261                intent = new Intent(Intent.ACTION_USER_STARTING);
11262                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11263                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11264                broadcastIntentLocked(null, null, intent,
11265                        null, new IIntentReceiver.Stub() {
11266                            @Override
11267                            public void performReceive(Intent intent, int resultCode, String data,
11268                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11269                                    throws RemoteException {
11270                            }
11271                        }, 0, null, null,
11272                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11273                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11274            } catch (Throwable t) {
11275                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11276            } finally {
11277                Binder.restoreCallingIdentity(ident);
11278            }
11279            mStackSupervisor.resumeTopActivitiesLocked();
11280            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11281        }
11282    }
11283
11284    private boolean makeAppCrashingLocked(ProcessRecord app,
11285            String shortMsg, String longMsg, String stackTrace) {
11286        app.crashing = true;
11287        app.crashingReport = generateProcessError(app,
11288                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11289        startAppProblemLocked(app);
11290        app.stopFreezingAllLocked();
11291        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11292    }
11293
11294    private void makeAppNotRespondingLocked(ProcessRecord app,
11295            String activity, String shortMsg, String longMsg) {
11296        app.notResponding = true;
11297        app.notRespondingReport = generateProcessError(app,
11298                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11299                activity, shortMsg, longMsg, null);
11300        startAppProblemLocked(app);
11301        app.stopFreezingAllLocked();
11302    }
11303
11304    /**
11305     * Generate a process error record, suitable for attachment to a ProcessRecord.
11306     *
11307     * @param app The ProcessRecord in which the error occurred.
11308     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11309     *                      ActivityManager.AppErrorStateInfo
11310     * @param activity The activity associated with the crash, if known.
11311     * @param shortMsg Short message describing the crash.
11312     * @param longMsg Long message describing the crash.
11313     * @param stackTrace Full crash stack trace, may be null.
11314     *
11315     * @return Returns a fully-formed AppErrorStateInfo record.
11316     */
11317    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11318            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11319        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11320
11321        report.condition = condition;
11322        report.processName = app.processName;
11323        report.pid = app.pid;
11324        report.uid = app.info.uid;
11325        report.tag = activity;
11326        report.shortMsg = shortMsg;
11327        report.longMsg = longMsg;
11328        report.stackTrace = stackTrace;
11329
11330        return report;
11331    }
11332
11333    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11334        synchronized (this) {
11335            app.crashing = false;
11336            app.crashingReport = null;
11337            app.notResponding = false;
11338            app.notRespondingReport = null;
11339            if (app.anrDialog == fromDialog) {
11340                app.anrDialog = null;
11341            }
11342            if (app.waitDialog == fromDialog) {
11343                app.waitDialog = null;
11344            }
11345            if (app.pid > 0 && app.pid != MY_PID) {
11346                handleAppCrashLocked(app, null, null, null);
11347                app.kill("user request after error", true);
11348            }
11349        }
11350    }
11351
11352    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11353            String stackTrace) {
11354        long now = SystemClock.uptimeMillis();
11355
11356        Long crashTime;
11357        if (!app.isolated) {
11358            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11359        } else {
11360            crashTime = null;
11361        }
11362        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11363            // This process loses!
11364            Slog.w(TAG, "Process " + app.info.processName
11365                    + " has crashed too many times: killing!");
11366            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11367                    app.userId, app.info.processName, app.uid);
11368            mStackSupervisor.handleAppCrashLocked(app);
11369            if (!app.persistent) {
11370                // We don't want to start this process again until the user
11371                // explicitly does so...  but for persistent process, we really
11372                // need to keep it running.  If a persistent process is actually
11373                // repeatedly crashing, then badness for everyone.
11374                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11375                        app.info.processName);
11376                if (!app.isolated) {
11377                    // XXX We don't have a way to mark isolated processes
11378                    // as bad, since they don't have a peristent identity.
11379                    mBadProcesses.put(app.info.processName, app.uid,
11380                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11381                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11382                }
11383                app.bad = true;
11384                app.removed = true;
11385                // Don't let services in this process be restarted and potentially
11386                // annoy the user repeatedly.  Unless it is persistent, since those
11387                // processes run critical code.
11388                removeProcessLocked(app, false, false, "crash");
11389                mStackSupervisor.resumeTopActivitiesLocked();
11390                return false;
11391            }
11392            mStackSupervisor.resumeTopActivitiesLocked();
11393        } else {
11394            mStackSupervisor.finishTopRunningActivityLocked(app);
11395        }
11396
11397        // Bump up the crash count of any services currently running in the proc.
11398        for (int i=app.services.size()-1; i>=0; i--) {
11399            // Any services running in the application need to be placed
11400            // back in the pending list.
11401            ServiceRecord sr = app.services.valueAt(i);
11402            sr.crashCount++;
11403        }
11404
11405        // If the crashing process is what we consider to be the "home process" and it has been
11406        // replaced by a third-party app, clear the package preferred activities from packages
11407        // with a home activity running in the process to prevent a repeatedly crashing app
11408        // from blocking the user to manually clear the list.
11409        final ArrayList<ActivityRecord> activities = app.activities;
11410        if (app == mHomeProcess && activities.size() > 0
11411                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11412            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11413                final ActivityRecord r = activities.get(activityNdx);
11414                if (r.isHomeActivity()) {
11415                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11416                    try {
11417                        ActivityThread.getPackageManager()
11418                                .clearPackagePreferredActivities(r.packageName);
11419                    } catch (RemoteException c) {
11420                        // pm is in same process, this will never happen.
11421                    }
11422                }
11423            }
11424        }
11425
11426        if (!app.isolated) {
11427            // XXX Can't keep track of crash times for isolated processes,
11428            // because they don't have a perisistent identity.
11429            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11430        }
11431
11432        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11433        return true;
11434    }
11435
11436    void startAppProblemLocked(ProcessRecord app) {
11437        // If this app is not running under the current user, then we
11438        // can't give it a report button because that would require
11439        // launching the report UI under a different user.
11440        app.errorReportReceiver = null;
11441
11442        for (int userId : mCurrentProfileIds) {
11443            if (app.userId == userId) {
11444                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11445                        mContext, app.info.packageName, app.info.flags);
11446            }
11447        }
11448        skipCurrentReceiverLocked(app);
11449    }
11450
11451    void skipCurrentReceiverLocked(ProcessRecord app) {
11452        for (BroadcastQueue queue : mBroadcastQueues) {
11453            queue.skipCurrentReceiverLocked(app);
11454        }
11455    }
11456
11457    /**
11458     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11459     * The application process will exit immediately after this call returns.
11460     * @param app object of the crashing app, null for the system server
11461     * @param crashInfo describing the exception
11462     */
11463    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11464        ProcessRecord r = findAppProcess(app, "Crash");
11465        final String processName = app == null ? "system_server"
11466                : (r == null ? "unknown" : r.processName);
11467
11468        handleApplicationCrashInner("crash", r, processName, crashInfo);
11469    }
11470
11471    /* Native crash reporting uses this inner version because it needs to be somewhat
11472     * decoupled from the AM-managed cleanup lifecycle
11473     */
11474    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11475            ApplicationErrorReport.CrashInfo crashInfo) {
11476        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11477                UserHandle.getUserId(Binder.getCallingUid()), processName,
11478                r == null ? -1 : r.info.flags,
11479                crashInfo.exceptionClassName,
11480                crashInfo.exceptionMessage,
11481                crashInfo.throwFileName,
11482                crashInfo.throwLineNumber);
11483
11484        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11485
11486        crashApplication(r, crashInfo);
11487    }
11488
11489    public void handleApplicationStrictModeViolation(
11490            IBinder app,
11491            int violationMask,
11492            StrictMode.ViolationInfo info) {
11493        ProcessRecord r = findAppProcess(app, "StrictMode");
11494        if (r == null) {
11495            return;
11496        }
11497
11498        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11499            Integer stackFingerprint = info.hashCode();
11500            boolean logIt = true;
11501            synchronized (mAlreadyLoggedViolatedStacks) {
11502                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11503                    logIt = false;
11504                    // TODO: sub-sample into EventLog for these, with
11505                    // the info.durationMillis?  Then we'd get
11506                    // the relative pain numbers, without logging all
11507                    // the stack traces repeatedly.  We'd want to do
11508                    // likewise in the client code, which also does
11509                    // dup suppression, before the Binder call.
11510                } else {
11511                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11512                        mAlreadyLoggedViolatedStacks.clear();
11513                    }
11514                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11515                }
11516            }
11517            if (logIt) {
11518                logStrictModeViolationToDropBox(r, info);
11519            }
11520        }
11521
11522        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11523            AppErrorResult result = new AppErrorResult();
11524            synchronized (this) {
11525                final long origId = Binder.clearCallingIdentity();
11526
11527                Message msg = Message.obtain();
11528                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11529                HashMap<String, Object> data = new HashMap<String, Object>();
11530                data.put("result", result);
11531                data.put("app", r);
11532                data.put("violationMask", violationMask);
11533                data.put("info", info);
11534                msg.obj = data;
11535                mHandler.sendMessage(msg);
11536
11537                Binder.restoreCallingIdentity(origId);
11538            }
11539            int res = result.get();
11540            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11541        }
11542    }
11543
11544    // Depending on the policy in effect, there could be a bunch of
11545    // these in quick succession so we try to batch these together to
11546    // minimize disk writes, number of dropbox entries, and maximize
11547    // compression, by having more fewer, larger records.
11548    private void logStrictModeViolationToDropBox(
11549            ProcessRecord process,
11550            StrictMode.ViolationInfo info) {
11551        if (info == null) {
11552            return;
11553        }
11554        final boolean isSystemApp = process == null ||
11555                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11556                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11557        final String processName = process == null ? "unknown" : process.processName;
11558        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11559        final DropBoxManager dbox = (DropBoxManager)
11560                mContext.getSystemService(Context.DROPBOX_SERVICE);
11561
11562        // Exit early if the dropbox isn't configured to accept this report type.
11563        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11564
11565        boolean bufferWasEmpty;
11566        boolean needsFlush;
11567        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11568        synchronized (sb) {
11569            bufferWasEmpty = sb.length() == 0;
11570            appendDropBoxProcessHeaders(process, processName, sb);
11571            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11572            sb.append("System-App: ").append(isSystemApp).append("\n");
11573            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11574            if (info.violationNumThisLoop != 0) {
11575                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11576            }
11577            if (info.numAnimationsRunning != 0) {
11578                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11579            }
11580            if (info.broadcastIntentAction != null) {
11581                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11582            }
11583            if (info.durationMillis != -1) {
11584                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11585            }
11586            if (info.numInstances != -1) {
11587                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11588            }
11589            if (info.tags != null) {
11590                for (String tag : info.tags) {
11591                    sb.append("Span-Tag: ").append(tag).append("\n");
11592                }
11593            }
11594            sb.append("\n");
11595            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11596                sb.append(info.crashInfo.stackTrace);
11597            }
11598            sb.append("\n");
11599
11600            // Only buffer up to ~64k.  Various logging bits truncate
11601            // things at 128k.
11602            needsFlush = (sb.length() > 64 * 1024);
11603        }
11604
11605        // Flush immediately if the buffer's grown too large, or this
11606        // is a non-system app.  Non-system apps are isolated with a
11607        // different tag & policy and not batched.
11608        //
11609        // Batching is useful during internal testing with
11610        // StrictMode settings turned up high.  Without batching,
11611        // thousands of separate files could be created on boot.
11612        if (!isSystemApp || needsFlush) {
11613            new Thread("Error dump: " + dropboxTag) {
11614                @Override
11615                public void run() {
11616                    String report;
11617                    synchronized (sb) {
11618                        report = sb.toString();
11619                        sb.delete(0, sb.length());
11620                        sb.trimToSize();
11621                    }
11622                    if (report.length() != 0) {
11623                        dbox.addText(dropboxTag, report);
11624                    }
11625                }
11626            }.start();
11627            return;
11628        }
11629
11630        // System app batching:
11631        if (!bufferWasEmpty) {
11632            // An existing dropbox-writing thread is outstanding, so
11633            // we don't need to start it up.  The existing thread will
11634            // catch the buffer appends we just did.
11635            return;
11636        }
11637
11638        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11639        // (After this point, we shouldn't access AMS internal data structures.)
11640        new Thread("Error dump: " + dropboxTag) {
11641            @Override
11642            public void run() {
11643                // 5 second sleep to let stacks arrive and be batched together
11644                try {
11645                    Thread.sleep(5000);  // 5 seconds
11646                } catch (InterruptedException e) {}
11647
11648                String errorReport;
11649                synchronized (mStrictModeBuffer) {
11650                    errorReport = mStrictModeBuffer.toString();
11651                    if (errorReport.length() == 0) {
11652                        return;
11653                    }
11654                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11655                    mStrictModeBuffer.trimToSize();
11656                }
11657                dbox.addText(dropboxTag, errorReport);
11658            }
11659        }.start();
11660    }
11661
11662    /**
11663     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11664     * @param app object of the crashing app, null for the system server
11665     * @param tag reported by the caller
11666     * @param system whether this wtf is coming from the system
11667     * @param crashInfo describing the context of the error
11668     * @return true if the process should exit immediately (WTF is fatal)
11669     */
11670    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11671            final ApplicationErrorReport.CrashInfo crashInfo) {
11672        final int callingUid = Binder.getCallingUid();
11673        final int callingPid = Binder.getCallingPid();
11674
11675        if (system) {
11676            // If this is coming from the system, we could very well have low-level
11677            // system locks held, so we want to do this all asynchronously.  And we
11678            // never want this to become fatal, so there is that too.
11679            mHandler.post(new Runnable() {
11680                @Override public void run() {
11681                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11682                }
11683            });
11684            return false;
11685        }
11686
11687        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11688                crashInfo);
11689
11690        if (r != null && r.pid != Process.myPid() &&
11691                Settings.Global.getInt(mContext.getContentResolver(),
11692                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11693            crashApplication(r, crashInfo);
11694            return true;
11695        } else {
11696            return false;
11697        }
11698    }
11699
11700    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11701            final ApplicationErrorReport.CrashInfo crashInfo) {
11702        final ProcessRecord r = findAppProcess(app, "WTF");
11703        final String processName = app == null ? "system_server"
11704                : (r == null ? "unknown" : r.processName);
11705
11706        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11707                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11708
11709        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11710
11711        return r;
11712    }
11713
11714    /**
11715     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11716     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11717     */
11718    private ProcessRecord findAppProcess(IBinder app, String reason) {
11719        if (app == null) {
11720            return null;
11721        }
11722
11723        synchronized (this) {
11724            final int NP = mProcessNames.getMap().size();
11725            for (int ip=0; ip<NP; ip++) {
11726                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11727                final int NA = apps.size();
11728                for (int ia=0; ia<NA; ia++) {
11729                    ProcessRecord p = apps.valueAt(ia);
11730                    if (p.thread != null && p.thread.asBinder() == app) {
11731                        return p;
11732                    }
11733                }
11734            }
11735
11736            Slog.w(TAG, "Can't find mystery application for " + reason
11737                    + " from pid=" + Binder.getCallingPid()
11738                    + " uid=" + Binder.getCallingUid() + ": " + app);
11739            return null;
11740        }
11741    }
11742
11743    /**
11744     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11745     * to append various headers to the dropbox log text.
11746     */
11747    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11748            StringBuilder sb) {
11749        // Watchdog thread ends up invoking this function (with
11750        // a null ProcessRecord) to add the stack file to dropbox.
11751        // Do not acquire a lock on this (am) in such cases, as it
11752        // could cause a potential deadlock, if and when watchdog
11753        // is invoked due to unavailability of lock on am and it
11754        // would prevent watchdog from killing system_server.
11755        if (process == null) {
11756            sb.append("Process: ").append(processName).append("\n");
11757            return;
11758        }
11759        // Note: ProcessRecord 'process' is guarded by the service
11760        // instance.  (notably process.pkgList, which could otherwise change
11761        // concurrently during execution of this method)
11762        synchronized (this) {
11763            sb.append("Process: ").append(processName).append("\n");
11764            int flags = process.info.flags;
11765            IPackageManager pm = AppGlobals.getPackageManager();
11766            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11767            for (int ip=0; ip<process.pkgList.size(); ip++) {
11768                String pkg = process.pkgList.keyAt(ip);
11769                sb.append("Package: ").append(pkg);
11770                try {
11771                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11772                    if (pi != null) {
11773                        sb.append(" v").append(pi.versionCode);
11774                        if (pi.versionName != null) {
11775                            sb.append(" (").append(pi.versionName).append(")");
11776                        }
11777                    }
11778                } catch (RemoteException e) {
11779                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11780                }
11781                sb.append("\n");
11782            }
11783        }
11784    }
11785
11786    private static String processClass(ProcessRecord process) {
11787        if (process == null || process.pid == MY_PID) {
11788            return "system_server";
11789        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11790            return "system_app";
11791        } else {
11792            return "data_app";
11793        }
11794    }
11795
11796    /**
11797     * Write a description of an error (crash, WTF, ANR) to the drop box.
11798     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11799     * @param process which caused the error, null means the system server
11800     * @param activity which triggered the error, null if unknown
11801     * @param parent activity related to the error, null if unknown
11802     * @param subject line related to the error, null if absent
11803     * @param report in long form describing the error, null if absent
11804     * @param logFile to include in the report, null if none
11805     * @param crashInfo giving an application stack trace, null if absent
11806     */
11807    public void addErrorToDropBox(String eventType,
11808            ProcessRecord process, String processName, ActivityRecord activity,
11809            ActivityRecord parent, String subject,
11810            final String report, final File logFile,
11811            final ApplicationErrorReport.CrashInfo crashInfo) {
11812        // NOTE -- this must never acquire the ActivityManagerService lock,
11813        // otherwise the watchdog may be prevented from resetting the system.
11814
11815        final String dropboxTag = processClass(process) + "_" + eventType;
11816        final DropBoxManager dbox = (DropBoxManager)
11817                mContext.getSystemService(Context.DROPBOX_SERVICE);
11818
11819        // Exit early if the dropbox isn't configured to accept this report type.
11820        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11821
11822        final StringBuilder sb = new StringBuilder(1024);
11823        appendDropBoxProcessHeaders(process, processName, sb);
11824        if (activity != null) {
11825            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11826        }
11827        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11828            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11829        }
11830        if (parent != null && parent != activity) {
11831            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11832        }
11833        if (subject != null) {
11834            sb.append("Subject: ").append(subject).append("\n");
11835        }
11836        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11837        if (Debug.isDebuggerConnected()) {
11838            sb.append("Debugger: Connected\n");
11839        }
11840        sb.append("\n");
11841
11842        // Do the rest in a worker thread to avoid blocking the caller on I/O
11843        // (After this point, we shouldn't access AMS internal data structures.)
11844        Thread worker = new Thread("Error dump: " + dropboxTag) {
11845            @Override
11846            public void run() {
11847                if (report != null) {
11848                    sb.append(report);
11849                }
11850                if (logFile != null) {
11851                    try {
11852                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11853                                    "\n\n[[TRUNCATED]]"));
11854                    } catch (IOException e) {
11855                        Slog.e(TAG, "Error reading " + logFile, e);
11856                    }
11857                }
11858                if (crashInfo != null && crashInfo.stackTrace != null) {
11859                    sb.append(crashInfo.stackTrace);
11860                }
11861
11862                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11863                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11864                if (lines > 0) {
11865                    sb.append("\n");
11866
11867                    // Merge several logcat streams, and take the last N lines
11868                    InputStreamReader input = null;
11869                    try {
11870                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11871                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11872                                "-b", "crash",
11873                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11874
11875                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11876                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11877                        input = new InputStreamReader(logcat.getInputStream());
11878
11879                        int num;
11880                        char[] buf = new char[8192];
11881                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11882                    } catch (IOException e) {
11883                        Slog.e(TAG, "Error running logcat", e);
11884                    } finally {
11885                        if (input != null) try { input.close(); } catch (IOException e) {}
11886                    }
11887                }
11888
11889                dbox.addText(dropboxTag, sb.toString());
11890            }
11891        };
11892
11893        if (process == null) {
11894            // If process is null, we are being called from some internal code
11895            // and may be about to die -- run this synchronously.
11896            worker.run();
11897        } else {
11898            worker.start();
11899        }
11900    }
11901
11902    /**
11903     * Bring up the "unexpected error" dialog box for a crashing app.
11904     * Deal with edge cases (intercepts from instrumented applications,
11905     * ActivityController, error intent receivers, that sort of thing).
11906     * @param r the application crashing
11907     * @param crashInfo describing the failure
11908     */
11909    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11910        long timeMillis = System.currentTimeMillis();
11911        String shortMsg = crashInfo.exceptionClassName;
11912        String longMsg = crashInfo.exceptionMessage;
11913        String stackTrace = crashInfo.stackTrace;
11914        if (shortMsg != null && longMsg != null) {
11915            longMsg = shortMsg + ": " + longMsg;
11916        } else if (shortMsg != null) {
11917            longMsg = shortMsg;
11918        }
11919
11920        AppErrorResult result = new AppErrorResult();
11921        synchronized (this) {
11922            if (mController != null) {
11923                try {
11924                    String name = r != null ? r.processName : null;
11925                    int pid = r != null ? r.pid : Binder.getCallingPid();
11926                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11927                    if (!mController.appCrashed(name, pid,
11928                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11929                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11930                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11931                            Slog.w(TAG, "Skip killing native crashed app " + name
11932                                    + "(" + pid + ") during testing");
11933                        } else {
11934                            Slog.w(TAG, "Force-killing crashed app " + name
11935                                    + " at watcher's request");
11936                            if (r != null) {
11937                                r.kill("crash", true);
11938                            } else {
11939                                // Huh.
11940                                Process.killProcess(pid);
11941                                Process.killProcessGroup(uid, pid);
11942                            }
11943                        }
11944                        return;
11945                    }
11946                } catch (RemoteException e) {
11947                    mController = null;
11948                    Watchdog.getInstance().setActivityController(null);
11949                }
11950            }
11951
11952            final long origId = Binder.clearCallingIdentity();
11953
11954            // If this process is running instrumentation, finish it.
11955            if (r != null && r.instrumentationClass != null) {
11956                Slog.w(TAG, "Error in app " + r.processName
11957                      + " running instrumentation " + r.instrumentationClass + ":");
11958                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11959                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11960                Bundle info = new Bundle();
11961                info.putString("shortMsg", shortMsg);
11962                info.putString("longMsg", longMsg);
11963                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11964                Binder.restoreCallingIdentity(origId);
11965                return;
11966            }
11967
11968            // If we can't identify the process or it's already exceeded its crash quota,
11969            // quit right away without showing a crash dialog.
11970            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11971                Binder.restoreCallingIdentity(origId);
11972                return;
11973            }
11974
11975            Message msg = Message.obtain();
11976            msg.what = SHOW_ERROR_MSG;
11977            HashMap data = new HashMap();
11978            data.put("result", result);
11979            data.put("app", r);
11980            msg.obj = data;
11981            mHandler.sendMessage(msg);
11982
11983            Binder.restoreCallingIdentity(origId);
11984        }
11985
11986        int res = result.get();
11987
11988        Intent appErrorIntent = null;
11989        synchronized (this) {
11990            if (r != null && !r.isolated) {
11991                // XXX Can't keep track of crash time for isolated processes,
11992                // since they don't have a persistent identity.
11993                mProcessCrashTimes.put(r.info.processName, r.uid,
11994                        SystemClock.uptimeMillis());
11995            }
11996            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11997                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11998            }
11999        }
12000
12001        if (appErrorIntent != null) {
12002            try {
12003                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12004            } catch (ActivityNotFoundException e) {
12005                Slog.w(TAG, "bug report receiver dissappeared", e);
12006            }
12007        }
12008    }
12009
12010    Intent createAppErrorIntentLocked(ProcessRecord r,
12011            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12012        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12013        if (report == null) {
12014            return null;
12015        }
12016        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12017        result.setComponent(r.errorReportReceiver);
12018        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12019        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12020        return result;
12021    }
12022
12023    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12024            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12025        if (r.errorReportReceiver == null) {
12026            return null;
12027        }
12028
12029        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12030            return null;
12031        }
12032
12033        ApplicationErrorReport report = new ApplicationErrorReport();
12034        report.packageName = r.info.packageName;
12035        report.installerPackageName = r.errorReportReceiver.getPackageName();
12036        report.processName = r.processName;
12037        report.time = timeMillis;
12038        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12039
12040        if (r.crashing || r.forceCrashReport) {
12041            report.type = ApplicationErrorReport.TYPE_CRASH;
12042            report.crashInfo = crashInfo;
12043        } else if (r.notResponding) {
12044            report.type = ApplicationErrorReport.TYPE_ANR;
12045            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12046
12047            report.anrInfo.activity = r.notRespondingReport.tag;
12048            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12049            report.anrInfo.info = r.notRespondingReport.longMsg;
12050        }
12051
12052        return report;
12053    }
12054
12055    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12056        enforceNotIsolatedCaller("getProcessesInErrorState");
12057        // assume our apps are happy - lazy create the list
12058        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12059
12060        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12061                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12062        int userId = UserHandle.getUserId(Binder.getCallingUid());
12063
12064        synchronized (this) {
12065
12066            // iterate across all processes
12067            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12068                ProcessRecord app = mLruProcesses.get(i);
12069                if (!allUsers && app.userId != userId) {
12070                    continue;
12071                }
12072                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12073                    // This one's in trouble, so we'll generate a report for it
12074                    // crashes are higher priority (in case there's a crash *and* an anr)
12075                    ActivityManager.ProcessErrorStateInfo report = null;
12076                    if (app.crashing) {
12077                        report = app.crashingReport;
12078                    } else if (app.notResponding) {
12079                        report = app.notRespondingReport;
12080                    }
12081
12082                    if (report != null) {
12083                        if (errList == null) {
12084                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12085                        }
12086                        errList.add(report);
12087                    } else {
12088                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12089                                " crashing = " + app.crashing +
12090                                " notResponding = " + app.notResponding);
12091                    }
12092                }
12093            }
12094        }
12095
12096        return errList;
12097    }
12098
12099    static int procStateToImportance(int procState, int memAdj,
12100            ActivityManager.RunningAppProcessInfo currApp) {
12101        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12102        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12103            currApp.lru = memAdj;
12104        } else {
12105            currApp.lru = 0;
12106        }
12107        return imp;
12108    }
12109
12110    private void fillInProcMemInfo(ProcessRecord app,
12111            ActivityManager.RunningAppProcessInfo outInfo) {
12112        outInfo.pid = app.pid;
12113        outInfo.uid = app.info.uid;
12114        if (mHeavyWeightProcess == app) {
12115            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12116        }
12117        if (app.persistent) {
12118            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12119        }
12120        if (app.activities.size() > 0) {
12121            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12122        }
12123        outInfo.lastTrimLevel = app.trimMemoryLevel;
12124        int adj = app.curAdj;
12125        int procState = app.curProcState;
12126        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12127        outInfo.importanceReasonCode = app.adjTypeCode;
12128        outInfo.processState = app.curProcState;
12129    }
12130
12131    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12132        enforceNotIsolatedCaller("getRunningAppProcesses");
12133        // Lazy instantiation of list
12134        List<ActivityManager.RunningAppProcessInfo> runList = null;
12135        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12136                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12137        int userId = UserHandle.getUserId(Binder.getCallingUid());
12138        synchronized (this) {
12139            // Iterate across all processes
12140            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12141                ProcessRecord app = mLruProcesses.get(i);
12142                if (!allUsers && app.userId != userId) {
12143                    continue;
12144                }
12145                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12146                    // Generate process state info for running application
12147                    ActivityManager.RunningAppProcessInfo currApp =
12148                        new ActivityManager.RunningAppProcessInfo(app.processName,
12149                                app.pid, app.getPackageList());
12150                    fillInProcMemInfo(app, currApp);
12151                    if (app.adjSource instanceof ProcessRecord) {
12152                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12153                        currApp.importanceReasonImportance =
12154                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12155                                        app.adjSourceProcState);
12156                    } else if (app.adjSource instanceof ActivityRecord) {
12157                        ActivityRecord r = (ActivityRecord)app.adjSource;
12158                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12159                    }
12160                    if (app.adjTarget instanceof ComponentName) {
12161                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12162                    }
12163                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12164                    //        + " lru=" + currApp.lru);
12165                    if (runList == null) {
12166                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12167                    }
12168                    runList.add(currApp);
12169                }
12170            }
12171        }
12172        return runList;
12173    }
12174
12175    public List<ApplicationInfo> getRunningExternalApplications() {
12176        enforceNotIsolatedCaller("getRunningExternalApplications");
12177        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12178        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12179        if (runningApps != null && runningApps.size() > 0) {
12180            Set<String> extList = new HashSet<String>();
12181            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12182                if (app.pkgList != null) {
12183                    for (String pkg : app.pkgList) {
12184                        extList.add(pkg);
12185                    }
12186                }
12187            }
12188            IPackageManager pm = AppGlobals.getPackageManager();
12189            for (String pkg : extList) {
12190                try {
12191                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12192                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12193                        retList.add(info);
12194                    }
12195                } catch (RemoteException e) {
12196                }
12197            }
12198        }
12199        return retList;
12200    }
12201
12202    @Override
12203    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12204        enforceNotIsolatedCaller("getMyMemoryState");
12205        synchronized (this) {
12206            ProcessRecord proc;
12207            synchronized (mPidsSelfLocked) {
12208                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12209            }
12210            fillInProcMemInfo(proc, outInfo);
12211        }
12212    }
12213
12214    @Override
12215    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12216        if (checkCallingPermission(android.Manifest.permission.DUMP)
12217                != PackageManager.PERMISSION_GRANTED) {
12218            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12219                    + Binder.getCallingPid()
12220                    + ", uid=" + Binder.getCallingUid()
12221                    + " without permission "
12222                    + android.Manifest.permission.DUMP);
12223            return;
12224        }
12225
12226        boolean dumpAll = false;
12227        boolean dumpClient = false;
12228        String dumpPackage = null;
12229
12230        int opti = 0;
12231        while (opti < args.length) {
12232            String opt = args[opti];
12233            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12234                break;
12235            }
12236            opti++;
12237            if ("-a".equals(opt)) {
12238                dumpAll = true;
12239            } else if ("-c".equals(opt)) {
12240                dumpClient = true;
12241            } else if ("-h".equals(opt)) {
12242                pw.println("Activity manager dump options:");
12243                pw.println("  [-a] [-c] [-h] [cmd] ...");
12244                pw.println("  cmd may be one of:");
12245                pw.println("    a[ctivities]: activity stack state");
12246                pw.println("    r[recents]: recent activities state");
12247                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12248                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12249                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12250                pw.println("    o[om]: out of memory management");
12251                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12252                pw.println("    provider [COMP_SPEC]: provider client-side state");
12253                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12254                pw.println("    service [COMP_SPEC]: service client-side state");
12255                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12256                pw.println("    all: dump all activities");
12257                pw.println("    top: dump the top activity");
12258                pw.println("    write: write all pending state to storage");
12259                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12260                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12261                pw.println("    a partial substring in a component name, a");
12262                pw.println("    hex object identifier.");
12263                pw.println("  -a: include all available server state.");
12264                pw.println("  -c: include client state.");
12265                return;
12266            } else {
12267                pw.println("Unknown argument: " + opt + "; use -h for help");
12268            }
12269        }
12270
12271        long origId = Binder.clearCallingIdentity();
12272        boolean more = false;
12273        // Is the caller requesting to dump a particular piece of data?
12274        if (opti < args.length) {
12275            String cmd = args[opti];
12276            opti++;
12277            if ("activities".equals(cmd) || "a".equals(cmd)) {
12278                synchronized (this) {
12279                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12280                }
12281            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12282                synchronized (this) {
12283                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12284                }
12285            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12286                String[] newArgs;
12287                String name;
12288                if (opti >= args.length) {
12289                    name = null;
12290                    newArgs = EMPTY_STRING_ARRAY;
12291                } else {
12292                    name = args[opti];
12293                    opti++;
12294                    newArgs = new String[args.length - opti];
12295                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12296                            args.length - opti);
12297                }
12298                synchronized (this) {
12299                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12300                }
12301            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12302                String[] newArgs;
12303                String name;
12304                if (opti >= args.length) {
12305                    name = null;
12306                    newArgs = EMPTY_STRING_ARRAY;
12307                } else {
12308                    name = args[opti];
12309                    opti++;
12310                    newArgs = new String[args.length - opti];
12311                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12312                            args.length - opti);
12313                }
12314                synchronized (this) {
12315                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12316                }
12317            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12318                String[] newArgs;
12319                String name;
12320                if (opti >= args.length) {
12321                    name = null;
12322                    newArgs = EMPTY_STRING_ARRAY;
12323                } else {
12324                    name = args[opti];
12325                    opti++;
12326                    newArgs = new String[args.length - opti];
12327                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12328                            args.length - opti);
12329                }
12330                synchronized (this) {
12331                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12332                }
12333            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12334                synchronized (this) {
12335                    dumpOomLocked(fd, pw, args, opti, true);
12336                }
12337            } else if ("provider".equals(cmd)) {
12338                String[] newArgs;
12339                String name;
12340                if (opti >= args.length) {
12341                    name = null;
12342                    newArgs = EMPTY_STRING_ARRAY;
12343                } else {
12344                    name = args[opti];
12345                    opti++;
12346                    newArgs = new String[args.length - opti];
12347                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12348                }
12349                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12350                    pw.println("No providers match: " + name);
12351                    pw.println("Use -h for help.");
12352                }
12353            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12354                synchronized (this) {
12355                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12356                }
12357            } else if ("service".equals(cmd)) {
12358                String[] newArgs;
12359                String name;
12360                if (opti >= args.length) {
12361                    name = null;
12362                    newArgs = EMPTY_STRING_ARRAY;
12363                } else {
12364                    name = args[opti];
12365                    opti++;
12366                    newArgs = new String[args.length - opti];
12367                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12368                            args.length - opti);
12369                }
12370                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12371                    pw.println("No services match: " + name);
12372                    pw.println("Use -h for help.");
12373                }
12374            } else if ("package".equals(cmd)) {
12375                String[] newArgs;
12376                if (opti >= args.length) {
12377                    pw.println("package: no package name specified");
12378                    pw.println("Use -h for help.");
12379                } else {
12380                    dumpPackage = args[opti];
12381                    opti++;
12382                    newArgs = new String[args.length - opti];
12383                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12384                            args.length - opti);
12385                    args = newArgs;
12386                    opti = 0;
12387                    more = true;
12388                }
12389            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12390                synchronized (this) {
12391                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12392                }
12393            } else if ("write".equals(cmd)) {
12394                mTaskPersister.flush();
12395                pw.println("All tasks persisted.");
12396                return;
12397            } else {
12398                // Dumping a single activity?
12399                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12400                    pw.println("Bad activity command, or no activities match: " + cmd);
12401                    pw.println("Use -h for help.");
12402                }
12403            }
12404            if (!more) {
12405                Binder.restoreCallingIdentity(origId);
12406                return;
12407            }
12408        }
12409
12410        // No piece of data specified, dump everything.
12411        synchronized (this) {
12412            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12413            pw.println();
12414            if (dumpAll) {
12415                pw.println("-------------------------------------------------------------------------------");
12416            }
12417            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12418            pw.println();
12419            if (dumpAll) {
12420                pw.println("-------------------------------------------------------------------------------");
12421            }
12422            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12423            pw.println();
12424            if (dumpAll) {
12425                pw.println("-------------------------------------------------------------------------------");
12426            }
12427            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12428            pw.println();
12429            if (dumpAll) {
12430                pw.println("-------------------------------------------------------------------------------");
12431            }
12432            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12433            pw.println();
12434            if (dumpAll) {
12435                pw.println("-------------------------------------------------------------------------------");
12436            }
12437            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12438            pw.println();
12439            if (dumpAll) {
12440                pw.println("-------------------------------------------------------------------------------");
12441            }
12442            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12443        }
12444        Binder.restoreCallingIdentity(origId);
12445    }
12446
12447    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12448            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12449        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12450
12451        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12452                dumpPackage);
12453        boolean needSep = printedAnything;
12454
12455        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12456                dumpPackage, needSep, "  mFocusedActivity: ");
12457        if (printed) {
12458            printedAnything = true;
12459            needSep = false;
12460        }
12461
12462        if (dumpPackage == null) {
12463            if (needSep) {
12464                pw.println();
12465            }
12466            needSep = true;
12467            printedAnything = true;
12468            mStackSupervisor.dump(pw, "  ");
12469        }
12470
12471        if (!printedAnything) {
12472            pw.println("  (nothing)");
12473        }
12474    }
12475
12476    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12477            int opti, boolean dumpAll, String dumpPackage) {
12478        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12479
12480        boolean printedAnything = false;
12481
12482        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12483            boolean printedHeader = false;
12484
12485            final int N = mRecentTasks.size();
12486            for (int i=0; i<N; i++) {
12487                TaskRecord tr = mRecentTasks.get(i);
12488                if (dumpPackage != null) {
12489                    if (tr.realActivity == null ||
12490                            !dumpPackage.equals(tr.realActivity)) {
12491                        continue;
12492                    }
12493                }
12494                if (!printedHeader) {
12495                    pw.println("  Recent tasks:");
12496                    printedHeader = true;
12497                    printedAnything = true;
12498                }
12499                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12500                        pw.println(tr);
12501                if (dumpAll) {
12502                    mRecentTasks.get(i).dump(pw, "    ");
12503                }
12504            }
12505        }
12506
12507        if (!printedAnything) {
12508            pw.println("  (nothing)");
12509        }
12510    }
12511
12512    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12513            int opti, boolean dumpAll, String dumpPackage) {
12514        boolean needSep = false;
12515        boolean printedAnything = false;
12516        int numPers = 0;
12517
12518        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12519
12520        if (dumpAll) {
12521            final int NP = mProcessNames.getMap().size();
12522            for (int ip=0; ip<NP; ip++) {
12523                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12524                final int NA = procs.size();
12525                for (int ia=0; ia<NA; ia++) {
12526                    ProcessRecord r = procs.valueAt(ia);
12527                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12528                        continue;
12529                    }
12530                    if (!needSep) {
12531                        pw.println("  All known processes:");
12532                        needSep = true;
12533                        printedAnything = true;
12534                    }
12535                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12536                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12537                        pw.print(" "); pw.println(r);
12538                    r.dump(pw, "    ");
12539                    if (r.persistent) {
12540                        numPers++;
12541                    }
12542                }
12543            }
12544        }
12545
12546        if (mIsolatedProcesses.size() > 0) {
12547            boolean printed = false;
12548            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12549                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12550                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12551                    continue;
12552                }
12553                if (!printed) {
12554                    if (needSep) {
12555                        pw.println();
12556                    }
12557                    pw.println("  Isolated process list (sorted by uid):");
12558                    printedAnything = true;
12559                    printed = true;
12560                    needSep = true;
12561                }
12562                pw.println(String.format("%sIsolated #%2d: %s",
12563                        "    ", i, r.toString()));
12564            }
12565        }
12566
12567        if (mLruProcesses.size() > 0) {
12568            if (needSep) {
12569                pw.println();
12570            }
12571            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12572                    pw.print(" total, non-act at ");
12573                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12574                    pw.print(", non-svc at ");
12575                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12576                    pw.println("):");
12577            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12578            needSep = true;
12579            printedAnything = true;
12580        }
12581
12582        if (dumpAll || dumpPackage != null) {
12583            synchronized (mPidsSelfLocked) {
12584                boolean printed = false;
12585                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12586                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12587                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12588                        continue;
12589                    }
12590                    if (!printed) {
12591                        if (needSep) pw.println();
12592                        needSep = true;
12593                        pw.println("  PID mappings:");
12594                        printed = true;
12595                        printedAnything = true;
12596                    }
12597                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12598                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12599                }
12600            }
12601        }
12602
12603        if (mForegroundProcesses.size() > 0) {
12604            synchronized (mPidsSelfLocked) {
12605                boolean printed = false;
12606                for (int i=0; i<mForegroundProcesses.size(); i++) {
12607                    ProcessRecord r = mPidsSelfLocked.get(
12608                            mForegroundProcesses.valueAt(i).pid);
12609                    if (dumpPackage != null && (r == null
12610                            || !r.pkgList.containsKey(dumpPackage))) {
12611                        continue;
12612                    }
12613                    if (!printed) {
12614                        if (needSep) pw.println();
12615                        needSep = true;
12616                        pw.println("  Foreground Processes:");
12617                        printed = true;
12618                        printedAnything = true;
12619                    }
12620                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12621                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12622                }
12623            }
12624        }
12625
12626        if (mPersistentStartingProcesses.size() > 0) {
12627            if (needSep) pw.println();
12628            needSep = true;
12629            printedAnything = true;
12630            pw.println("  Persisent processes that are starting:");
12631            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12632                    "Starting Norm", "Restarting PERS", dumpPackage);
12633        }
12634
12635        if (mRemovedProcesses.size() > 0) {
12636            if (needSep) pw.println();
12637            needSep = true;
12638            printedAnything = true;
12639            pw.println("  Processes that are being removed:");
12640            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12641                    "Removed Norm", "Removed PERS", dumpPackage);
12642        }
12643
12644        if (mProcessesOnHold.size() > 0) {
12645            if (needSep) pw.println();
12646            needSep = true;
12647            printedAnything = true;
12648            pw.println("  Processes that are on old until the system is ready:");
12649            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12650                    "OnHold Norm", "OnHold PERS", dumpPackage);
12651        }
12652
12653        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12654
12655        if (mProcessCrashTimes.getMap().size() > 0) {
12656            boolean printed = false;
12657            long now = SystemClock.uptimeMillis();
12658            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12659            final int NP = pmap.size();
12660            for (int ip=0; ip<NP; ip++) {
12661                String pname = pmap.keyAt(ip);
12662                SparseArray<Long> uids = pmap.valueAt(ip);
12663                final int N = uids.size();
12664                for (int i=0; i<N; i++) {
12665                    int puid = uids.keyAt(i);
12666                    ProcessRecord r = mProcessNames.get(pname, puid);
12667                    if (dumpPackage != null && (r == null
12668                            || !r.pkgList.containsKey(dumpPackage))) {
12669                        continue;
12670                    }
12671                    if (!printed) {
12672                        if (needSep) pw.println();
12673                        needSep = true;
12674                        pw.println("  Time since processes crashed:");
12675                        printed = true;
12676                        printedAnything = true;
12677                    }
12678                    pw.print("    Process "); pw.print(pname);
12679                            pw.print(" uid "); pw.print(puid);
12680                            pw.print(": last crashed ");
12681                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12682                            pw.println(" ago");
12683                }
12684            }
12685        }
12686
12687        if (mBadProcesses.getMap().size() > 0) {
12688            boolean printed = false;
12689            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12690            final int NP = pmap.size();
12691            for (int ip=0; ip<NP; ip++) {
12692                String pname = pmap.keyAt(ip);
12693                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12694                final int N = uids.size();
12695                for (int i=0; i<N; i++) {
12696                    int puid = uids.keyAt(i);
12697                    ProcessRecord r = mProcessNames.get(pname, puid);
12698                    if (dumpPackage != null && (r == null
12699                            || !r.pkgList.containsKey(dumpPackage))) {
12700                        continue;
12701                    }
12702                    if (!printed) {
12703                        if (needSep) pw.println();
12704                        needSep = true;
12705                        pw.println("  Bad processes:");
12706                        printedAnything = true;
12707                    }
12708                    BadProcessInfo info = uids.valueAt(i);
12709                    pw.print("    Bad process "); pw.print(pname);
12710                            pw.print(" uid "); pw.print(puid);
12711                            pw.print(": crashed at time "); pw.println(info.time);
12712                    if (info.shortMsg != null) {
12713                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12714                    }
12715                    if (info.longMsg != null) {
12716                        pw.print("      Long msg: "); pw.println(info.longMsg);
12717                    }
12718                    if (info.stack != null) {
12719                        pw.println("      Stack:");
12720                        int lastPos = 0;
12721                        for (int pos=0; pos<info.stack.length(); pos++) {
12722                            if (info.stack.charAt(pos) == '\n') {
12723                                pw.print("        ");
12724                                pw.write(info.stack, lastPos, pos-lastPos);
12725                                pw.println();
12726                                lastPos = pos+1;
12727                            }
12728                        }
12729                        if (lastPos < info.stack.length()) {
12730                            pw.print("        ");
12731                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12732                            pw.println();
12733                        }
12734                    }
12735                }
12736            }
12737        }
12738
12739        if (dumpPackage == null) {
12740            pw.println();
12741            needSep = false;
12742            pw.println("  mStartedUsers:");
12743            for (int i=0; i<mStartedUsers.size(); i++) {
12744                UserStartedState uss = mStartedUsers.valueAt(i);
12745                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12746                        pw.print(": "); uss.dump("", pw);
12747            }
12748            pw.print("  mStartedUserArray: [");
12749            for (int i=0; i<mStartedUserArray.length; i++) {
12750                if (i > 0) pw.print(", ");
12751                pw.print(mStartedUserArray[i]);
12752            }
12753            pw.println("]");
12754            pw.print("  mUserLru: [");
12755            for (int i=0; i<mUserLru.size(); i++) {
12756                if (i > 0) pw.print(", ");
12757                pw.print(mUserLru.get(i));
12758            }
12759            pw.println("]");
12760            if (dumpAll) {
12761                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12762            }
12763            synchronized (mUserProfileGroupIdsSelfLocked) {
12764                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12765                    pw.println("  mUserProfileGroupIds:");
12766                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12767                        pw.print("    User #");
12768                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12769                        pw.print(" -> profile #");
12770                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12771                    }
12772                }
12773            }
12774        }
12775        if (mHomeProcess != null && (dumpPackage == null
12776                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12777            if (needSep) {
12778                pw.println();
12779                needSep = false;
12780            }
12781            pw.println("  mHomeProcess: " + mHomeProcess);
12782        }
12783        if (mPreviousProcess != null && (dumpPackage == null
12784                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12785            if (needSep) {
12786                pw.println();
12787                needSep = false;
12788            }
12789            pw.println("  mPreviousProcess: " + mPreviousProcess);
12790        }
12791        if (dumpAll) {
12792            StringBuilder sb = new StringBuilder(128);
12793            sb.append("  mPreviousProcessVisibleTime: ");
12794            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12795            pw.println(sb);
12796        }
12797        if (mHeavyWeightProcess != null && (dumpPackage == null
12798                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12799            if (needSep) {
12800                pw.println();
12801                needSep = false;
12802            }
12803            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12804        }
12805        if (dumpPackage == null) {
12806            pw.println("  mConfiguration: " + mConfiguration);
12807        }
12808        if (dumpAll) {
12809            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12810            if (mCompatModePackages.getPackages().size() > 0) {
12811                boolean printed = false;
12812                for (Map.Entry<String, Integer> entry
12813                        : mCompatModePackages.getPackages().entrySet()) {
12814                    String pkg = entry.getKey();
12815                    int mode = entry.getValue();
12816                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12817                        continue;
12818                    }
12819                    if (!printed) {
12820                        pw.println("  mScreenCompatPackages:");
12821                        printed = true;
12822                    }
12823                    pw.print("    "); pw.print(pkg); pw.print(": ");
12824                            pw.print(mode); pw.println();
12825                }
12826            }
12827        }
12828        if (dumpPackage == null) {
12829            if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) {
12830                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12831                        + " mLockScreenShown " + lockScreenShownToString());
12832            }
12833            if (mShuttingDown || mRunningVoice) {
12834                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12835            }
12836        }
12837        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12838                || mOrigWaitForDebugger) {
12839            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12840                    || dumpPackage.equals(mOrigDebugApp)) {
12841                if (needSep) {
12842                    pw.println();
12843                    needSep = false;
12844                }
12845                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12846                        + " mDebugTransient=" + mDebugTransient
12847                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12848            }
12849        }
12850        if (mOpenGlTraceApp != null) {
12851            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12852                if (needSep) {
12853                    pw.println();
12854                    needSep = false;
12855                }
12856                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12857            }
12858        }
12859        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12860                || mProfileFd != null) {
12861            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12862                if (needSep) {
12863                    pw.println();
12864                    needSep = false;
12865                }
12866                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12867                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12868                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12869                        + mAutoStopProfiler);
12870                pw.println("  mProfileType=" + mProfileType);
12871            }
12872        }
12873        if (dumpPackage == null) {
12874            if (mAlwaysFinishActivities || mController != null) {
12875                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12876                        + " mController=" + mController);
12877            }
12878            if (dumpAll) {
12879                pw.println("  Total persistent processes: " + numPers);
12880                pw.println("  mProcessesReady=" + mProcessesReady
12881                        + " mSystemReady=" + mSystemReady
12882                        + " mBooted=" + mBooted
12883                        + " mFactoryTest=" + mFactoryTest);
12884                pw.println("  mBooting=" + mBooting
12885                        + " mCallFinishBooting=" + mCallFinishBooting
12886                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12887                pw.print("  mLastPowerCheckRealtime=");
12888                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12889                        pw.println("");
12890                pw.print("  mLastPowerCheckUptime=");
12891                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12892                        pw.println("");
12893                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12894                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12895                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12896                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12897                        + " (" + mLruProcesses.size() + " total)"
12898                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12899                        + " mNumServiceProcs=" + mNumServiceProcs
12900                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12901                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12902                        + " mLastMemoryLevel" + mLastMemoryLevel
12903                        + " mLastNumProcesses" + mLastNumProcesses);
12904                long now = SystemClock.uptimeMillis();
12905                pw.print("  mLastIdleTime=");
12906                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12907                        pw.print(" mLowRamSinceLastIdle=");
12908                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12909                        pw.println();
12910            }
12911        }
12912
12913        if (!printedAnything) {
12914            pw.println("  (nothing)");
12915        }
12916    }
12917
12918    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12919            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12920        if (mProcessesToGc.size() > 0) {
12921            boolean printed = false;
12922            long now = SystemClock.uptimeMillis();
12923            for (int i=0; i<mProcessesToGc.size(); i++) {
12924                ProcessRecord proc = mProcessesToGc.get(i);
12925                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12926                    continue;
12927                }
12928                if (!printed) {
12929                    if (needSep) pw.println();
12930                    needSep = true;
12931                    pw.println("  Processes that are waiting to GC:");
12932                    printed = true;
12933                }
12934                pw.print("    Process "); pw.println(proc);
12935                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12936                        pw.print(", last gced=");
12937                        pw.print(now-proc.lastRequestedGc);
12938                        pw.print(" ms ago, last lowMem=");
12939                        pw.print(now-proc.lastLowMemory);
12940                        pw.println(" ms ago");
12941
12942            }
12943        }
12944        return needSep;
12945    }
12946
12947    void printOomLevel(PrintWriter pw, String name, int adj) {
12948        pw.print("    ");
12949        if (adj >= 0) {
12950            pw.print(' ');
12951            if (adj < 10) pw.print(' ');
12952        } else {
12953            if (adj > -10) pw.print(' ');
12954        }
12955        pw.print(adj);
12956        pw.print(": ");
12957        pw.print(name);
12958        pw.print(" (");
12959        pw.print(mProcessList.getMemLevel(adj)/1024);
12960        pw.println(" kB)");
12961    }
12962
12963    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12964            int opti, boolean dumpAll) {
12965        boolean needSep = false;
12966
12967        if (mLruProcesses.size() > 0) {
12968            if (needSep) pw.println();
12969            needSep = true;
12970            pw.println("  OOM levels:");
12971            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12972            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12973            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12974            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12975            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12976            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12977            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12978            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12979            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12980            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12981            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12982            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12983            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12984            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12985
12986            if (needSep) pw.println();
12987            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12988                    pw.print(" total, non-act at ");
12989                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12990                    pw.print(", non-svc at ");
12991                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12992                    pw.println("):");
12993            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12994            needSep = true;
12995        }
12996
12997        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12998
12999        pw.println();
13000        pw.println("  mHomeProcess: " + mHomeProcess);
13001        pw.println("  mPreviousProcess: " + mPreviousProcess);
13002        if (mHeavyWeightProcess != null) {
13003            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13004        }
13005
13006        return true;
13007    }
13008
13009    /**
13010     * There are three ways to call this:
13011     *  - no provider specified: dump all the providers
13012     *  - a flattened component name that matched an existing provider was specified as the
13013     *    first arg: dump that one provider
13014     *  - the first arg isn't the flattened component name of an existing provider:
13015     *    dump all providers whose component contains the first arg as a substring
13016     */
13017    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13018            int opti, boolean dumpAll) {
13019        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13020    }
13021
13022    static class ItemMatcher {
13023        ArrayList<ComponentName> components;
13024        ArrayList<String> strings;
13025        ArrayList<Integer> objects;
13026        boolean all;
13027
13028        ItemMatcher() {
13029            all = true;
13030        }
13031
13032        void build(String name) {
13033            ComponentName componentName = ComponentName.unflattenFromString(name);
13034            if (componentName != null) {
13035                if (components == null) {
13036                    components = new ArrayList<ComponentName>();
13037                }
13038                components.add(componentName);
13039                all = false;
13040            } else {
13041                int objectId = 0;
13042                // Not a '/' separated full component name; maybe an object ID?
13043                try {
13044                    objectId = Integer.parseInt(name, 16);
13045                    if (objects == null) {
13046                        objects = new ArrayList<Integer>();
13047                    }
13048                    objects.add(objectId);
13049                    all = false;
13050                } catch (RuntimeException e) {
13051                    // Not an integer; just do string match.
13052                    if (strings == null) {
13053                        strings = new ArrayList<String>();
13054                    }
13055                    strings.add(name);
13056                    all = false;
13057                }
13058            }
13059        }
13060
13061        int build(String[] args, int opti) {
13062            for (; opti<args.length; opti++) {
13063                String name = args[opti];
13064                if ("--".equals(name)) {
13065                    return opti+1;
13066                }
13067                build(name);
13068            }
13069            return opti;
13070        }
13071
13072        boolean match(Object object, ComponentName comp) {
13073            if (all) {
13074                return true;
13075            }
13076            if (components != null) {
13077                for (int i=0; i<components.size(); i++) {
13078                    if (components.get(i).equals(comp)) {
13079                        return true;
13080                    }
13081                }
13082            }
13083            if (objects != null) {
13084                for (int i=0; i<objects.size(); i++) {
13085                    if (System.identityHashCode(object) == objects.get(i)) {
13086                        return true;
13087                    }
13088                }
13089            }
13090            if (strings != null) {
13091                String flat = comp.flattenToString();
13092                for (int i=0; i<strings.size(); i++) {
13093                    if (flat.contains(strings.get(i))) {
13094                        return true;
13095                    }
13096                }
13097            }
13098            return false;
13099        }
13100    }
13101
13102    /**
13103     * There are three things that cmd can be:
13104     *  - a flattened component name that matches an existing activity
13105     *  - the cmd arg isn't the flattened component name of an existing activity:
13106     *    dump all activity whose component contains the cmd as a substring
13107     *  - A hex number of the ActivityRecord object instance.
13108     */
13109    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13110            int opti, boolean dumpAll) {
13111        ArrayList<ActivityRecord> activities;
13112
13113        synchronized (this) {
13114            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13115        }
13116
13117        if (activities.size() <= 0) {
13118            return false;
13119        }
13120
13121        String[] newArgs = new String[args.length - opti];
13122        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13123
13124        TaskRecord lastTask = null;
13125        boolean needSep = false;
13126        for (int i=activities.size()-1; i>=0; i--) {
13127            ActivityRecord r = activities.get(i);
13128            if (needSep) {
13129                pw.println();
13130            }
13131            needSep = true;
13132            synchronized (this) {
13133                if (lastTask != r.task) {
13134                    lastTask = r.task;
13135                    pw.print("TASK "); pw.print(lastTask.affinity);
13136                            pw.print(" id="); pw.println(lastTask.taskId);
13137                    if (dumpAll) {
13138                        lastTask.dump(pw, "  ");
13139                    }
13140                }
13141            }
13142            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13143        }
13144        return true;
13145    }
13146
13147    /**
13148     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13149     * there is a thread associated with the activity.
13150     */
13151    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13152            final ActivityRecord r, String[] args, boolean dumpAll) {
13153        String innerPrefix = prefix + "  ";
13154        synchronized (this) {
13155            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13156                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13157                    pw.print(" pid=");
13158                    if (r.app != null) pw.println(r.app.pid);
13159                    else pw.println("(not running)");
13160            if (dumpAll) {
13161                r.dump(pw, innerPrefix);
13162            }
13163        }
13164        if (r.app != null && r.app.thread != null) {
13165            // flush anything that is already in the PrintWriter since the thread is going
13166            // to write to the file descriptor directly
13167            pw.flush();
13168            try {
13169                TransferPipe tp = new TransferPipe();
13170                try {
13171                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13172                            r.appToken, innerPrefix, args);
13173                    tp.go(fd);
13174                } finally {
13175                    tp.kill();
13176                }
13177            } catch (IOException e) {
13178                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13179            } catch (RemoteException e) {
13180                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13181            }
13182        }
13183    }
13184
13185    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13186            int opti, boolean dumpAll, String dumpPackage) {
13187        boolean needSep = false;
13188        boolean onlyHistory = false;
13189        boolean printedAnything = false;
13190
13191        if ("history".equals(dumpPackage)) {
13192            if (opti < args.length && "-s".equals(args[opti])) {
13193                dumpAll = false;
13194            }
13195            onlyHistory = true;
13196            dumpPackage = null;
13197        }
13198
13199        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13200        if (!onlyHistory && dumpAll) {
13201            if (mRegisteredReceivers.size() > 0) {
13202                boolean printed = false;
13203                Iterator it = mRegisteredReceivers.values().iterator();
13204                while (it.hasNext()) {
13205                    ReceiverList r = (ReceiverList)it.next();
13206                    if (dumpPackage != null && (r.app == null ||
13207                            !dumpPackage.equals(r.app.info.packageName))) {
13208                        continue;
13209                    }
13210                    if (!printed) {
13211                        pw.println("  Registered Receivers:");
13212                        needSep = true;
13213                        printed = true;
13214                        printedAnything = true;
13215                    }
13216                    pw.print("  * "); pw.println(r);
13217                    r.dump(pw, "    ");
13218                }
13219            }
13220
13221            if (mReceiverResolver.dump(pw, needSep ?
13222                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13223                    "    ", dumpPackage, false)) {
13224                needSep = true;
13225                printedAnything = true;
13226            }
13227        }
13228
13229        for (BroadcastQueue q : mBroadcastQueues) {
13230            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13231            printedAnything |= needSep;
13232        }
13233
13234        needSep = true;
13235
13236        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13237            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13238                if (needSep) {
13239                    pw.println();
13240                }
13241                needSep = true;
13242                printedAnything = true;
13243                pw.print("  Sticky broadcasts for user ");
13244                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13245                StringBuilder sb = new StringBuilder(128);
13246                for (Map.Entry<String, ArrayList<Intent>> ent
13247                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13248                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13249                    if (dumpAll) {
13250                        pw.println(":");
13251                        ArrayList<Intent> intents = ent.getValue();
13252                        final int N = intents.size();
13253                        for (int i=0; i<N; i++) {
13254                            sb.setLength(0);
13255                            sb.append("    Intent: ");
13256                            intents.get(i).toShortString(sb, false, true, false, false);
13257                            pw.println(sb.toString());
13258                            Bundle bundle = intents.get(i).getExtras();
13259                            if (bundle != null) {
13260                                pw.print("      ");
13261                                pw.println(bundle.toString());
13262                            }
13263                        }
13264                    } else {
13265                        pw.println("");
13266                    }
13267                }
13268            }
13269        }
13270
13271        if (!onlyHistory && dumpAll) {
13272            pw.println();
13273            for (BroadcastQueue queue : mBroadcastQueues) {
13274                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13275                        + queue.mBroadcastsScheduled);
13276            }
13277            pw.println("  mHandler:");
13278            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13279            needSep = true;
13280            printedAnything = true;
13281        }
13282
13283        if (!printedAnything) {
13284            pw.println("  (nothing)");
13285        }
13286    }
13287
13288    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13289            int opti, boolean dumpAll, String dumpPackage) {
13290        boolean needSep;
13291        boolean printedAnything = false;
13292
13293        ItemMatcher matcher = new ItemMatcher();
13294        matcher.build(args, opti);
13295
13296        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13297
13298        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13299        printedAnything |= needSep;
13300
13301        if (mLaunchingProviders.size() > 0) {
13302            boolean printed = false;
13303            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13304                ContentProviderRecord r = mLaunchingProviders.get(i);
13305                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13306                    continue;
13307                }
13308                if (!printed) {
13309                    if (needSep) pw.println();
13310                    needSep = true;
13311                    pw.println("  Launching content providers:");
13312                    printed = true;
13313                    printedAnything = true;
13314                }
13315                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13316                        pw.println(r);
13317            }
13318        }
13319
13320        if (mGrantedUriPermissions.size() > 0) {
13321            boolean printed = false;
13322            int dumpUid = -2;
13323            if (dumpPackage != null) {
13324                try {
13325                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13326                } catch (NameNotFoundException e) {
13327                    dumpUid = -1;
13328                }
13329            }
13330            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13331                int uid = mGrantedUriPermissions.keyAt(i);
13332                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13333                    continue;
13334                }
13335                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13336                if (!printed) {
13337                    if (needSep) pw.println();
13338                    needSep = true;
13339                    pw.println("  Granted Uri Permissions:");
13340                    printed = true;
13341                    printedAnything = true;
13342                }
13343                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13344                for (UriPermission perm : perms.values()) {
13345                    pw.print("    "); pw.println(perm);
13346                    if (dumpAll) {
13347                        perm.dump(pw, "      ");
13348                    }
13349                }
13350            }
13351        }
13352
13353        if (!printedAnything) {
13354            pw.println("  (nothing)");
13355        }
13356    }
13357
13358    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13359            int opti, boolean dumpAll, String dumpPackage) {
13360        boolean printed = false;
13361
13362        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13363
13364        if (mIntentSenderRecords.size() > 0) {
13365            Iterator<WeakReference<PendingIntentRecord>> it
13366                    = mIntentSenderRecords.values().iterator();
13367            while (it.hasNext()) {
13368                WeakReference<PendingIntentRecord> ref = it.next();
13369                PendingIntentRecord rec = ref != null ? ref.get(): null;
13370                if (dumpPackage != null && (rec == null
13371                        || !dumpPackage.equals(rec.key.packageName))) {
13372                    continue;
13373                }
13374                printed = true;
13375                if (rec != null) {
13376                    pw.print("  * "); pw.println(rec);
13377                    if (dumpAll) {
13378                        rec.dump(pw, "    ");
13379                    }
13380                } else {
13381                    pw.print("  * "); pw.println(ref);
13382                }
13383            }
13384        }
13385
13386        if (!printed) {
13387            pw.println("  (nothing)");
13388        }
13389    }
13390
13391    private static final int dumpProcessList(PrintWriter pw,
13392            ActivityManagerService service, List list,
13393            String prefix, String normalLabel, String persistentLabel,
13394            String dumpPackage) {
13395        int numPers = 0;
13396        final int N = list.size()-1;
13397        for (int i=N; i>=0; i--) {
13398            ProcessRecord r = (ProcessRecord)list.get(i);
13399            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13400                continue;
13401            }
13402            pw.println(String.format("%s%s #%2d: %s",
13403                    prefix, (r.persistent ? persistentLabel : normalLabel),
13404                    i, r.toString()));
13405            if (r.persistent) {
13406                numPers++;
13407            }
13408        }
13409        return numPers;
13410    }
13411
13412    private static final boolean dumpProcessOomList(PrintWriter pw,
13413            ActivityManagerService service, List<ProcessRecord> origList,
13414            String prefix, String normalLabel, String persistentLabel,
13415            boolean inclDetails, String dumpPackage) {
13416
13417        ArrayList<Pair<ProcessRecord, Integer>> list
13418                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13419        for (int i=0; i<origList.size(); i++) {
13420            ProcessRecord r = origList.get(i);
13421            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13422                continue;
13423            }
13424            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13425        }
13426
13427        if (list.size() <= 0) {
13428            return false;
13429        }
13430
13431        Comparator<Pair<ProcessRecord, Integer>> comparator
13432                = new Comparator<Pair<ProcessRecord, Integer>>() {
13433            @Override
13434            public int compare(Pair<ProcessRecord, Integer> object1,
13435                    Pair<ProcessRecord, Integer> object2) {
13436                if (object1.first.setAdj != object2.first.setAdj) {
13437                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13438                }
13439                if (object1.second.intValue() != object2.second.intValue()) {
13440                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13441                }
13442                return 0;
13443            }
13444        };
13445
13446        Collections.sort(list, comparator);
13447
13448        final long curRealtime = SystemClock.elapsedRealtime();
13449        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13450        final long curUptime = SystemClock.uptimeMillis();
13451        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13452
13453        for (int i=list.size()-1; i>=0; i--) {
13454            ProcessRecord r = list.get(i).first;
13455            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13456            char schedGroup;
13457            switch (r.setSchedGroup) {
13458                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13459                    schedGroup = 'B';
13460                    break;
13461                case Process.THREAD_GROUP_DEFAULT:
13462                    schedGroup = 'F';
13463                    break;
13464                default:
13465                    schedGroup = '?';
13466                    break;
13467            }
13468            char foreground;
13469            if (r.foregroundActivities) {
13470                foreground = 'A';
13471            } else if (r.foregroundServices) {
13472                foreground = 'S';
13473            } else {
13474                foreground = ' ';
13475            }
13476            String procState = ProcessList.makeProcStateString(r.curProcState);
13477            pw.print(prefix);
13478            pw.print(r.persistent ? persistentLabel : normalLabel);
13479            pw.print(" #");
13480            int num = (origList.size()-1)-list.get(i).second;
13481            if (num < 10) pw.print(' ');
13482            pw.print(num);
13483            pw.print(": ");
13484            pw.print(oomAdj);
13485            pw.print(' ');
13486            pw.print(schedGroup);
13487            pw.print('/');
13488            pw.print(foreground);
13489            pw.print('/');
13490            pw.print(procState);
13491            pw.print(" trm:");
13492            if (r.trimMemoryLevel < 10) pw.print(' ');
13493            pw.print(r.trimMemoryLevel);
13494            pw.print(' ');
13495            pw.print(r.toShortString());
13496            pw.print(" (");
13497            pw.print(r.adjType);
13498            pw.println(')');
13499            if (r.adjSource != null || r.adjTarget != null) {
13500                pw.print(prefix);
13501                pw.print("    ");
13502                if (r.adjTarget instanceof ComponentName) {
13503                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13504                } else if (r.adjTarget != null) {
13505                    pw.print(r.adjTarget.toString());
13506                } else {
13507                    pw.print("{null}");
13508                }
13509                pw.print("<=");
13510                if (r.adjSource instanceof ProcessRecord) {
13511                    pw.print("Proc{");
13512                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13513                    pw.println("}");
13514                } else if (r.adjSource != null) {
13515                    pw.println(r.adjSource.toString());
13516                } else {
13517                    pw.println("{null}");
13518                }
13519            }
13520            if (inclDetails) {
13521                pw.print(prefix);
13522                pw.print("    ");
13523                pw.print("oom: max="); pw.print(r.maxAdj);
13524                pw.print(" curRaw="); pw.print(r.curRawAdj);
13525                pw.print(" setRaw="); pw.print(r.setRawAdj);
13526                pw.print(" cur="); pw.print(r.curAdj);
13527                pw.print(" set="); pw.println(r.setAdj);
13528                pw.print(prefix);
13529                pw.print("    ");
13530                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13531                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13532                pw.print(" lastPss="); pw.print(r.lastPss);
13533                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13534                pw.print(prefix);
13535                pw.print("    ");
13536                pw.print("cached="); pw.print(r.cached);
13537                pw.print(" empty="); pw.print(r.empty);
13538                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13539
13540                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13541                    if (r.lastWakeTime != 0) {
13542                        long wtime;
13543                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13544                        synchronized (stats) {
13545                            wtime = stats.getProcessWakeTime(r.info.uid,
13546                                    r.pid, curRealtime);
13547                        }
13548                        long timeUsed = wtime - r.lastWakeTime;
13549                        pw.print(prefix);
13550                        pw.print("    ");
13551                        pw.print("keep awake over ");
13552                        TimeUtils.formatDuration(realtimeSince, pw);
13553                        pw.print(" used ");
13554                        TimeUtils.formatDuration(timeUsed, pw);
13555                        pw.print(" (");
13556                        pw.print((timeUsed*100)/realtimeSince);
13557                        pw.println("%)");
13558                    }
13559                    if (r.lastCpuTime != 0) {
13560                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13561                        pw.print(prefix);
13562                        pw.print("    ");
13563                        pw.print("run cpu over ");
13564                        TimeUtils.formatDuration(uptimeSince, pw);
13565                        pw.print(" used ");
13566                        TimeUtils.formatDuration(timeUsed, pw);
13567                        pw.print(" (");
13568                        pw.print((timeUsed*100)/uptimeSince);
13569                        pw.println("%)");
13570                    }
13571                }
13572            }
13573        }
13574        return true;
13575    }
13576
13577    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13578            String[] args) {
13579        ArrayList<ProcessRecord> procs;
13580        synchronized (this) {
13581            if (args != null && args.length > start
13582                    && args[start].charAt(0) != '-') {
13583                procs = new ArrayList<ProcessRecord>();
13584                int pid = -1;
13585                try {
13586                    pid = Integer.parseInt(args[start]);
13587                } catch (NumberFormatException e) {
13588                }
13589                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13590                    ProcessRecord proc = mLruProcesses.get(i);
13591                    if (proc.pid == pid) {
13592                        procs.add(proc);
13593                    } else if (allPkgs && proc.pkgList != null
13594                            && proc.pkgList.containsKey(args[start])) {
13595                        procs.add(proc);
13596                    } else if (proc.processName.equals(args[start])) {
13597                        procs.add(proc);
13598                    }
13599                }
13600                if (procs.size() <= 0) {
13601                    return null;
13602                }
13603            } else {
13604                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13605            }
13606        }
13607        return procs;
13608    }
13609
13610    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13611            PrintWriter pw, String[] args) {
13612        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13613        if (procs == null) {
13614            pw.println("No process found for: " + args[0]);
13615            return;
13616        }
13617
13618        long uptime = SystemClock.uptimeMillis();
13619        long realtime = SystemClock.elapsedRealtime();
13620        pw.println("Applications Graphics Acceleration Info:");
13621        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13622
13623        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13624            ProcessRecord r = procs.get(i);
13625            if (r.thread != null) {
13626                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13627                pw.flush();
13628                try {
13629                    TransferPipe tp = new TransferPipe();
13630                    try {
13631                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13632                        tp.go(fd);
13633                    } finally {
13634                        tp.kill();
13635                    }
13636                } catch (IOException e) {
13637                    pw.println("Failure while dumping the app: " + r);
13638                    pw.flush();
13639                } catch (RemoteException e) {
13640                    pw.println("Got a RemoteException while dumping the app " + r);
13641                    pw.flush();
13642                }
13643            }
13644        }
13645    }
13646
13647    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13648        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13649        if (procs == null) {
13650            pw.println("No process found for: " + args[0]);
13651            return;
13652        }
13653
13654        pw.println("Applications Database Info:");
13655
13656        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13657            ProcessRecord r = procs.get(i);
13658            if (r.thread != null) {
13659                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13660                pw.flush();
13661                try {
13662                    TransferPipe tp = new TransferPipe();
13663                    try {
13664                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13665                        tp.go(fd);
13666                    } finally {
13667                        tp.kill();
13668                    }
13669                } catch (IOException e) {
13670                    pw.println("Failure while dumping the app: " + r);
13671                    pw.flush();
13672                } catch (RemoteException e) {
13673                    pw.println("Got a RemoteException while dumping the app " + r);
13674                    pw.flush();
13675                }
13676            }
13677        }
13678    }
13679
13680    final static class MemItem {
13681        final boolean isProc;
13682        final String label;
13683        final String shortLabel;
13684        final long pss;
13685        final int id;
13686        final boolean hasActivities;
13687        ArrayList<MemItem> subitems;
13688
13689        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13690                boolean _hasActivities) {
13691            isProc = true;
13692            label = _label;
13693            shortLabel = _shortLabel;
13694            pss = _pss;
13695            id = _id;
13696            hasActivities = _hasActivities;
13697        }
13698
13699        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13700            isProc = false;
13701            label = _label;
13702            shortLabel = _shortLabel;
13703            pss = _pss;
13704            id = _id;
13705            hasActivities = false;
13706        }
13707    }
13708
13709    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13710            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13711        if (sort && !isCompact) {
13712            Collections.sort(items, new Comparator<MemItem>() {
13713                @Override
13714                public int compare(MemItem lhs, MemItem rhs) {
13715                    if (lhs.pss < rhs.pss) {
13716                        return 1;
13717                    } else if (lhs.pss > rhs.pss) {
13718                        return -1;
13719                    }
13720                    return 0;
13721                }
13722            });
13723        }
13724
13725        for (int i=0; i<items.size(); i++) {
13726            MemItem mi = items.get(i);
13727            if (!isCompact) {
13728                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13729            } else if (mi.isProc) {
13730                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13731                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13732                pw.println(mi.hasActivities ? ",a" : ",e");
13733            } else {
13734                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13735                pw.println(mi.pss);
13736            }
13737            if (mi.subitems != null) {
13738                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13739                        true, isCompact);
13740            }
13741        }
13742    }
13743
13744    // These are in KB.
13745    static final long[] DUMP_MEM_BUCKETS = new long[] {
13746        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13747        120*1024, 160*1024, 200*1024,
13748        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13749        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13750    };
13751
13752    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13753            boolean stackLike) {
13754        int start = label.lastIndexOf('.');
13755        if (start >= 0) start++;
13756        else start = 0;
13757        int end = label.length();
13758        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13759            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13760                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13761                out.append(bucket);
13762                out.append(stackLike ? "MB." : "MB ");
13763                out.append(label, start, end);
13764                return;
13765            }
13766        }
13767        out.append(memKB/1024);
13768        out.append(stackLike ? "MB." : "MB ");
13769        out.append(label, start, end);
13770    }
13771
13772    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13773            ProcessList.NATIVE_ADJ,
13774            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13775            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13776            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13777            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13778            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13779            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13780    };
13781    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13782            "Native",
13783            "System", "Persistent", "Persistent Service", "Foreground",
13784            "Visible", "Perceptible",
13785            "Heavy Weight", "Backup",
13786            "A Services", "Home",
13787            "Previous", "B Services", "Cached"
13788    };
13789    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13790            "native",
13791            "sys", "pers", "persvc", "fore",
13792            "vis", "percept",
13793            "heavy", "backup",
13794            "servicea", "home",
13795            "prev", "serviceb", "cached"
13796    };
13797
13798    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13799            long realtime, boolean isCheckinRequest, boolean isCompact) {
13800        if (isCheckinRequest || isCompact) {
13801            // short checkin version
13802            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13803        } else {
13804            pw.println("Applications Memory Usage (kB):");
13805            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13806        }
13807    }
13808
13809    private static final int KSM_SHARED = 0;
13810    private static final int KSM_SHARING = 1;
13811    private static final int KSM_UNSHARED = 2;
13812    private static final int KSM_VOLATILE = 3;
13813
13814    private final long[] getKsmInfo() {
13815        long[] longOut = new long[4];
13816        final int[] SINGLE_LONG_FORMAT = new int[] {
13817            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13818        };
13819        long[] longTmp = new long[1];
13820        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13821                SINGLE_LONG_FORMAT, null, longTmp, null);
13822        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13823        longTmp[0] = 0;
13824        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13825                SINGLE_LONG_FORMAT, null, longTmp, null);
13826        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13827        longTmp[0] = 0;
13828        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13829                SINGLE_LONG_FORMAT, null, longTmp, null);
13830        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13831        longTmp[0] = 0;
13832        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13833                SINGLE_LONG_FORMAT, null, longTmp, null);
13834        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13835        return longOut;
13836    }
13837
13838    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13839            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13840        boolean dumpDetails = false;
13841        boolean dumpFullDetails = false;
13842        boolean dumpDalvik = false;
13843        boolean oomOnly = false;
13844        boolean isCompact = false;
13845        boolean localOnly = false;
13846        boolean packages = false;
13847
13848        int opti = 0;
13849        while (opti < args.length) {
13850            String opt = args[opti];
13851            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13852                break;
13853            }
13854            opti++;
13855            if ("-a".equals(opt)) {
13856                dumpDetails = true;
13857                dumpFullDetails = true;
13858                dumpDalvik = true;
13859            } else if ("-d".equals(opt)) {
13860                dumpDalvik = true;
13861            } else if ("-c".equals(opt)) {
13862                isCompact = true;
13863            } else if ("--oom".equals(opt)) {
13864                oomOnly = true;
13865            } else if ("--local".equals(opt)) {
13866                localOnly = true;
13867            } else if ("--package".equals(opt)) {
13868                packages = true;
13869            } else if ("-h".equals(opt)) {
13870                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13871                pw.println("  -a: include all available information for each process.");
13872                pw.println("  -d: include dalvik details when dumping process details.");
13873                pw.println("  -c: dump in a compact machine-parseable representation.");
13874                pw.println("  --oom: only show processes organized by oom adj.");
13875                pw.println("  --local: only collect details locally, don't call process.");
13876                pw.println("  --package: interpret process arg as package, dumping all");
13877                pw.println("             processes that have loaded that package.");
13878                pw.println("If [process] is specified it can be the name or ");
13879                pw.println("pid of a specific process to dump.");
13880                return;
13881            } else {
13882                pw.println("Unknown argument: " + opt + "; use -h for help");
13883            }
13884        }
13885
13886        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13887        long uptime = SystemClock.uptimeMillis();
13888        long realtime = SystemClock.elapsedRealtime();
13889        final long[] tmpLong = new long[1];
13890
13891        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13892        if (procs == null) {
13893            // No Java processes.  Maybe they want to print a native process.
13894            if (args != null && args.length > opti
13895                    && args[opti].charAt(0) != '-') {
13896                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13897                        = new ArrayList<ProcessCpuTracker.Stats>();
13898                updateCpuStatsNow();
13899                int findPid = -1;
13900                try {
13901                    findPid = Integer.parseInt(args[opti]);
13902                } catch (NumberFormatException e) {
13903                }
13904                synchronized (mProcessCpuTracker) {
13905                    final int N = mProcessCpuTracker.countStats();
13906                    for (int i=0; i<N; i++) {
13907                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13908                        if (st.pid == findPid || (st.baseName != null
13909                                && st.baseName.equals(args[opti]))) {
13910                            nativeProcs.add(st);
13911                        }
13912                    }
13913                }
13914                if (nativeProcs.size() > 0) {
13915                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13916                            isCompact);
13917                    Debug.MemoryInfo mi = null;
13918                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13919                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13920                        final int pid = r.pid;
13921                        if (!isCheckinRequest && dumpDetails) {
13922                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13923                        }
13924                        if (mi == null) {
13925                            mi = new Debug.MemoryInfo();
13926                        }
13927                        if (dumpDetails || (!brief && !oomOnly)) {
13928                            Debug.getMemoryInfo(pid, mi);
13929                        } else {
13930                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13931                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13932                        }
13933                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13934                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13935                        if (isCheckinRequest) {
13936                            pw.println();
13937                        }
13938                    }
13939                    return;
13940                }
13941            }
13942            pw.println("No process found for: " + args[opti]);
13943            return;
13944        }
13945
13946        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13947            dumpDetails = true;
13948        }
13949
13950        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13951
13952        String[] innerArgs = new String[args.length-opti];
13953        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13954
13955        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13956        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13957        long nativePss = 0;
13958        long dalvikPss = 0;
13959        long otherPss = 0;
13960        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13961
13962        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13963        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13964                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13965
13966        long totalPss = 0;
13967        long cachedPss = 0;
13968
13969        Debug.MemoryInfo mi = null;
13970        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13971            final ProcessRecord r = procs.get(i);
13972            final IApplicationThread thread;
13973            final int pid;
13974            final int oomAdj;
13975            final boolean hasActivities;
13976            synchronized (this) {
13977                thread = r.thread;
13978                pid = r.pid;
13979                oomAdj = r.getSetAdjWithServices();
13980                hasActivities = r.activities.size() > 0;
13981            }
13982            if (thread != null) {
13983                if (!isCheckinRequest && dumpDetails) {
13984                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13985                }
13986                if (mi == null) {
13987                    mi = new Debug.MemoryInfo();
13988                }
13989                if (dumpDetails || (!brief && !oomOnly)) {
13990                    Debug.getMemoryInfo(pid, mi);
13991                } else {
13992                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13993                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13994                }
13995                if (dumpDetails) {
13996                    if (localOnly) {
13997                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13998                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13999                        if (isCheckinRequest) {
14000                            pw.println();
14001                        }
14002                    } else {
14003                        try {
14004                            pw.flush();
14005                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14006                                    dumpDalvik, innerArgs);
14007                        } catch (RemoteException e) {
14008                            if (!isCheckinRequest) {
14009                                pw.println("Got RemoteException!");
14010                                pw.flush();
14011                            }
14012                        }
14013                    }
14014                }
14015
14016                final long myTotalPss = mi.getTotalPss();
14017                final long myTotalUss = mi.getTotalUss();
14018
14019                synchronized (this) {
14020                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14021                        // Record this for posterity if the process has been stable.
14022                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14023                    }
14024                }
14025
14026                if (!isCheckinRequest && mi != null) {
14027                    totalPss += myTotalPss;
14028                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14029                            (hasActivities ? " / activities)" : ")"),
14030                            r.processName, myTotalPss, pid, hasActivities);
14031                    procMems.add(pssItem);
14032                    procMemsMap.put(pid, pssItem);
14033
14034                    nativePss += mi.nativePss;
14035                    dalvikPss += mi.dalvikPss;
14036                    otherPss += mi.otherPss;
14037                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14038                        long mem = mi.getOtherPss(j);
14039                        miscPss[j] += mem;
14040                        otherPss -= mem;
14041                    }
14042
14043                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14044                        cachedPss += myTotalPss;
14045                    }
14046
14047                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14048                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14049                                || oomIndex == (oomPss.length-1)) {
14050                            oomPss[oomIndex] += myTotalPss;
14051                            if (oomProcs[oomIndex] == null) {
14052                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14053                            }
14054                            oomProcs[oomIndex].add(pssItem);
14055                            break;
14056                        }
14057                    }
14058                }
14059            }
14060        }
14061
14062        long nativeProcTotalPss = 0;
14063
14064        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14065            // If we are showing aggregations, also look for native processes to
14066            // include so that our aggregations are more accurate.
14067            updateCpuStatsNow();
14068            synchronized (mProcessCpuTracker) {
14069                final int N = mProcessCpuTracker.countStats();
14070                for (int i=0; i<N; i++) {
14071                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14072                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14073                        if (mi == null) {
14074                            mi = new Debug.MemoryInfo();
14075                        }
14076                        if (!brief && !oomOnly) {
14077                            Debug.getMemoryInfo(st.pid, mi);
14078                        } else {
14079                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14080                            mi.nativePrivateDirty = (int)tmpLong[0];
14081                        }
14082
14083                        final long myTotalPss = mi.getTotalPss();
14084                        totalPss += myTotalPss;
14085                        nativeProcTotalPss += myTotalPss;
14086
14087                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14088                                st.name, myTotalPss, st.pid, false);
14089                        procMems.add(pssItem);
14090
14091                        nativePss += mi.nativePss;
14092                        dalvikPss += mi.dalvikPss;
14093                        otherPss += mi.otherPss;
14094                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14095                            long mem = mi.getOtherPss(j);
14096                            miscPss[j] += mem;
14097                            otherPss -= mem;
14098                        }
14099                        oomPss[0] += myTotalPss;
14100                        if (oomProcs[0] == null) {
14101                            oomProcs[0] = new ArrayList<MemItem>();
14102                        }
14103                        oomProcs[0].add(pssItem);
14104                    }
14105                }
14106            }
14107
14108            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14109
14110            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14111            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14112            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14113            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14114                String label = Debug.MemoryInfo.getOtherLabel(j);
14115                catMems.add(new MemItem(label, label, miscPss[j], j));
14116            }
14117
14118            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14119            for (int j=0; j<oomPss.length; j++) {
14120                if (oomPss[j] != 0) {
14121                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14122                            : DUMP_MEM_OOM_LABEL[j];
14123                    MemItem item = new MemItem(label, label, oomPss[j],
14124                            DUMP_MEM_OOM_ADJ[j]);
14125                    item.subitems = oomProcs[j];
14126                    oomMems.add(item);
14127                }
14128            }
14129
14130            if (!brief && !oomOnly && !isCompact) {
14131                pw.println();
14132                pw.println("Total PSS by process:");
14133                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14134                pw.println();
14135            }
14136            if (!isCompact) {
14137                pw.println("Total PSS by OOM adjustment:");
14138            }
14139            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14140            if (!brief && !oomOnly) {
14141                PrintWriter out = categoryPw != null ? categoryPw : pw;
14142                if (!isCompact) {
14143                    out.println();
14144                    out.println("Total PSS by category:");
14145                }
14146                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14147            }
14148            if (!isCompact) {
14149                pw.println();
14150            }
14151            MemInfoReader memInfo = new MemInfoReader();
14152            memInfo.readMemInfo();
14153            if (nativeProcTotalPss > 0) {
14154                synchronized (this) {
14155                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14156                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14157                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14158                }
14159            }
14160            if (!brief) {
14161                if (!isCompact) {
14162                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14163                    pw.print(" kB (status ");
14164                    switch (mLastMemoryLevel) {
14165                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14166                            pw.println("normal)");
14167                            break;
14168                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14169                            pw.println("moderate)");
14170                            break;
14171                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14172                            pw.println("low)");
14173                            break;
14174                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14175                            pw.println("critical)");
14176                            break;
14177                        default:
14178                            pw.print(mLastMemoryLevel);
14179                            pw.println(")");
14180                            break;
14181                    }
14182                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14183                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14184                            pw.print(cachedPss); pw.print(" cached pss + ");
14185                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14186                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14187                } else {
14188                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14189                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14190                            + memInfo.getFreeSizeKb()); pw.print(",");
14191                    pw.println(totalPss - cachedPss);
14192                }
14193            }
14194            if (!isCompact) {
14195                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14196                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14197                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14198                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14199                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14200                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14201                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14202            }
14203            if (!brief) {
14204                if (memInfo.getZramTotalSizeKb() != 0) {
14205                    if (!isCompact) {
14206                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14207                                pw.print(" kB physical used for ");
14208                                pw.print(memInfo.getSwapTotalSizeKb()
14209                                        - memInfo.getSwapFreeSizeKb());
14210                                pw.print(" kB in swap (");
14211                                pw.print(memInfo.getSwapTotalSizeKb());
14212                                pw.println(" kB total swap)");
14213                    } else {
14214                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14215                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14216                                pw.println(memInfo.getSwapFreeSizeKb());
14217                    }
14218                }
14219                final long[] ksm = getKsmInfo();
14220                if (!isCompact) {
14221                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14222                            || ksm[KSM_VOLATILE] != 0) {
14223                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14224                                pw.print(" kB saved from shared ");
14225                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14226                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14227                                pw.print(" kB unshared; ");
14228                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14229                    }
14230                    pw.print("   Tuning: ");
14231                    pw.print(ActivityManager.staticGetMemoryClass());
14232                    pw.print(" (large ");
14233                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14234                    pw.print("), oom ");
14235                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14236                    pw.print(" kB");
14237                    pw.print(", restore limit ");
14238                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14239                    pw.print(" kB");
14240                    if (ActivityManager.isLowRamDeviceStatic()) {
14241                        pw.print(" (low-ram)");
14242                    }
14243                    if (ActivityManager.isHighEndGfx()) {
14244                        pw.print(" (high-end-gfx)");
14245                    }
14246                    pw.println();
14247                } else {
14248                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14249                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14250                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14251                    pw.print("tuning,");
14252                    pw.print(ActivityManager.staticGetMemoryClass());
14253                    pw.print(',');
14254                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14255                    pw.print(',');
14256                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14257                    if (ActivityManager.isLowRamDeviceStatic()) {
14258                        pw.print(",low-ram");
14259                    }
14260                    if (ActivityManager.isHighEndGfx()) {
14261                        pw.print(",high-end-gfx");
14262                    }
14263                    pw.println();
14264                }
14265            }
14266        }
14267    }
14268
14269    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14270            String name) {
14271        sb.append("  ");
14272        sb.append(ProcessList.makeOomAdjString(oomAdj));
14273        sb.append(' ');
14274        sb.append(ProcessList.makeProcStateString(procState));
14275        sb.append(' ');
14276        ProcessList.appendRamKb(sb, pss);
14277        sb.append(" kB: ");
14278        sb.append(name);
14279    }
14280
14281    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14282        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14283        sb.append(" (");
14284        sb.append(mi.pid);
14285        sb.append(") ");
14286        sb.append(mi.adjType);
14287        sb.append('\n');
14288        if (mi.adjReason != null) {
14289            sb.append("                      ");
14290            sb.append(mi.adjReason);
14291            sb.append('\n');
14292        }
14293    }
14294
14295    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14296        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14297        for (int i=0, N=memInfos.size(); i<N; i++) {
14298            ProcessMemInfo mi = memInfos.get(i);
14299            infoMap.put(mi.pid, mi);
14300        }
14301        updateCpuStatsNow();
14302        synchronized (mProcessCpuTracker) {
14303            final int N = mProcessCpuTracker.countStats();
14304            for (int i=0; i<N; i++) {
14305                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14306                if (st.vsize > 0) {
14307                    long pss = Debug.getPss(st.pid, null);
14308                    if (pss > 0) {
14309                        if (infoMap.indexOfKey(st.pid) < 0) {
14310                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14311                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14312                            mi.pss = pss;
14313                            memInfos.add(mi);
14314                        }
14315                    }
14316                }
14317            }
14318        }
14319
14320        long totalPss = 0;
14321        for (int i=0, N=memInfos.size(); i<N; i++) {
14322            ProcessMemInfo mi = memInfos.get(i);
14323            if (mi.pss == 0) {
14324                mi.pss = Debug.getPss(mi.pid, null);
14325            }
14326            totalPss += mi.pss;
14327        }
14328        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14329            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14330                if (lhs.oomAdj != rhs.oomAdj) {
14331                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14332                }
14333                if (lhs.pss != rhs.pss) {
14334                    return lhs.pss < rhs.pss ? 1 : -1;
14335                }
14336                return 0;
14337            }
14338        });
14339
14340        StringBuilder tag = new StringBuilder(128);
14341        StringBuilder stack = new StringBuilder(128);
14342        tag.append("Low on memory -- ");
14343        appendMemBucket(tag, totalPss, "total", false);
14344        appendMemBucket(stack, totalPss, "total", true);
14345
14346        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14347        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14348        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14349
14350        boolean firstLine = true;
14351        int lastOomAdj = Integer.MIN_VALUE;
14352        long extraNativeRam = 0;
14353        long cachedPss = 0;
14354        for (int i=0, N=memInfos.size(); i<N; i++) {
14355            ProcessMemInfo mi = memInfos.get(i);
14356
14357            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14358                cachedPss += mi.pss;
14359            }
14360
14361            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14362                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14363                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14364                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14365                if (lastOomAdj != mi.oomAdj) {
14366                    lastOomAdj = mi.oomAdj;
14367                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14368                        tag.append(" / ");
14369                    }
14370                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14371                        if (firstLine) {
14372                            stack.append(":");
14373                            firstLine = false;
14374                        }
14375                        stack.append("\n\t at ");
14376                    } else {
14377                        stack.append("$");
14378                    }
14379                } else {
14380                    tag.append(" ");
14381                    stack.append("$");
14382                }
14383                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14384                    appendMemBucket(tag, mi.pss, mi.name, false);
14385                }
14386                appendMemBucket(stack, mi.pss, mi.name, true);
14387                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14388                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14389                    stack.append("(");
14390                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14391                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14392                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14393                            stack.append(":");
14394                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14395                        }
14396                    }
14397                    stack.append(")");
14398                }
14399            }
14400
14401            appendMemInfo(fullNativeBuilder, mi);
14402            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14403                // The short form only has native processes that are >= 1MB.
14404                if (mi.pss >= 1000) {
14405                    appendMemInfo(shortNativeBuilder, mi);
14406                } else {
14407                    extraNativeRam += mi.pss;
14408                }
14409            } else {
14410                // Short form has all other details, but if we have collected RAM
14411                // from smaller native processes let's dump a summary of that.
14412                if (extraNativeRam > 0) {
14413                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14414                            -1, extraNativeRam, "(Other native)");
14415                    shortNativeBuilder.append('\n');
14416                    extraNativeRam = 0;
14417                }
14418                appendMemInfo(fullJavaBuilder, mi);
14419            }
14420        }
14421
14422        fullJavaBuilder.append("           ");
14423        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14424        fullJavaBuilder.append(" kB: TOTAL\n");
14425
14426        MemInfoReader memInfo = new MemInfoReader();
14427        memInfo.readMemInfo();
14428        final long[] infos = memInfo.getRawInfo();
14429
14430        StringBuilder memInfoBuilder = new StringBuilder(1024);
14431        Debug.getMemInfo(infos);
14432        memInfoBuilder.append("  MemInfo: ");
14433        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14434        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14435        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14436        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14437        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14438        memInfoBuilder.append("           ");
14439        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14440        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14441        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14442        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14443        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14444            memInfoBuilder.append("  ZRAM: ");
14445            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14446            memInfoBuilder.append(" kB RAM, ");
14447            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14448            memInfoBuilder.append(" kB swap total, ");
14449            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14450            memInfoBuilder.append(" kB swap free\n");
14451        }
14452        final long[] ksm = getKsmInfo();
14453        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14454                || ksm[KSM_VOLATILE] != 0) {
14455            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14456            memInfoBuilder.append(" kB saved from shared ");
14457            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14458            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14459            memInfoBuilder.append(" kB unshared; ");
14460            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14461        }
14462        memInfoBuilder.append("  Free RAM: ");
14463        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14464                + memInfo.getFreeSizeKb());
14465        memInfoBuilder.append(" kB\n");
14466        memInfoBuilder.append("  Used RAM: ");
14467        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14468        memInfoBuilder.append(" kB\n");
14469        memInfoBuilder.append("  Lost RAM: ");
14470        memInfoBuilder.append(memInfo.getTotalSizeKb()
14471                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14472                - memInfo.getKernelUsedSizeKb());
14473        memInfoBuilder.append(" kB\n");
14474        Slog.i(TAG, "Low on memory:");
14475        Slog.i(TAG, shortNativeBuilder.toString());
14476        Slog.i(TAG, fullJavaBuilder.toString());
14477        Slog.i(TAG, memInfoBuilder.toString());
14478
14479        StringBuilder dropBuilder = new StringBuilder(1024);
14480        /*
14481        StringWriter oomSw = new StringWriter();
14482        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14483        StringWriter catSw = new StringWriter();
14484        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14485        String[] emptyArgs = new String[] { };
14486        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14487        oomPw.flush();
14488        String oomString = oomSw.toString();
14489        */
14490        dropBuilder.append("Low on memory:");
14491        dropBuilder.append(stack);
14492        dropBuilder.append('\n');
14493        dropBuilder.append(fullNativeBuilder);
14494        dropBuilder.append(fullJavaBuilder);
14495        dropBuilder.append('\n');
14496        dropBuilder.append(memInfoBuilder);
14497        dropBuilder.append('\n');
14498        /*
14499        dropBuilder.append(oomString);
14500        dropBuilder.append('\n');
14501        */
14502        StringWriter catSw = new StringWriter();
14503        synchronized (ActivityManagerService.this) {
14504            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14505            String[] emptyArgs = new String[] { };
14506            catPw.println();
14507            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14508            catPw.println();
14509            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14510                    false, false, null);
14511            catPw.println();
14512            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14513            catPw.flush();
14514        }
14515        dropBuilder.append(catSw.toString());
14516        addErrorToDropBox("lowmem", null, "system_server", null,
14517                null, tag.toString(), dropBuilder.toString(), null, null);
14518        //Slog.i(TAG, "Sent to dropbox:");
14519        //Slog.i(TAG, dropBuilder.toString());
14520        synchronized (ActivityManagerService.this) {
14521            long now = SystemClock.uptimeMillis();
14522            if (mLastMemUsageReportTime < now) {
14523                mLastMemUsageReportTime = now;
14524            }
14525        }
14526    }
14527
14528    /**
14529     * Searches array of arguments for the specified string
14530     * @param args array of argument strings
14531     * @param value value to search for
14532     * @return true if the value is contained in the array
14533     */
14534    private static boolean scanArgs(String[] args, String value) {
14535        if (args != null) {
14536            for (String arg : args) {
14537                if (value.equals(arg)) {
14538                    return true;
14539                }
14540            }
14541        }
14542        return false;
14543    }
14544
14545    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14546            ContentProviderRecord cpr, boolean always) {
14547        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14548
14549        if (!inLaunching || always) {
14550            synchronized (cpr) {
14551                cpr.launchingApp = null;
14552                cpr.notifyAll();
14553            }
14554            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14555            String names[] = cpr.info.authority.split(";");
14556            for (int j = 0; j < names.length; j++) {
14557                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14558            }
14559        }
14560
14561        for (int i=0; i<cpr.connections.size(); i++) {
14562            ContentProviderConnection conn = cpr.connections.get(i);
14563            if (conn.waiting) {
14564                // If this connection is waiting for the provider, then we don't
14565                // need to mess with its process unless we are always removing
14566                // or for some reason the provider is not currently launching.
14567                if (inLaunching && !always) {
14568                    continue;
14569                }
14570            }
14571            ProcessRecord capp = conn.client;
14572            conn.dead = true;
14573            if (conn.stableCount > 0) {
14574                if (!capp.persistent && capp.thread != null
14575                        && capp.pid != 0
14576                        && capp.pid != MY_PID) {
14577                    capp.kill("depends on provider "
14578                            + cpr.name.flattenToShortString()
14579                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14580                }
14581            } else if (capp.thread != null && conn.provider.provider != null) {
14582                try {
14583                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14584                } catch (RemoteException e) {
14585                }
14586                // In the protocol here, we don't expect the client to correctly
14587                // clean up this connection, we'll just remove it.
14588                cpr.connections.remove(i);
14589                conn.client.conProviders.remove(conn);
14590            }
14591        }
14592
14593        if (inLaunching && always) {
14594            mLaunchingProviders.remove(cpr);
14595        }
14596        return inLaunching;
14597    }
14598
14599    /**
14600     * Main code for cleaning up a process when it has gone away.  This is
14601     * called both as a result of the process dying, or directly when stopping
14602     * a process when running in single process mode.
14603     *
14604     * @return Returns true if the given process has been restarted, so the
14605     * app that was passed in must remain on the process lists.
14606     */
14607    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14608            boolean restarting, boolean allowRestart, int index) {
14609        if (index >= 0) {
14610            removeLruProcessLocked(app);
14611            ProcessList.remove(app.pid);
14612        }
14613
14614        mProcessesToGc.remove(app);
14615        mPendingPssProcesses.remove(app);
14616
14617        // Dismiss any open dialogs.
14618        if (app.crashDialog != null && !app.forceCrashReport) {
14619            app.crashDialog.dismiss();
14620            app.crashDialog = null;
14621        }
14622        if (app.anrDialog != null) {
14623            app.anrDialog.dismiss();
14624            app.anrDialog = null;
14625        }
14626        if (app.waitDialog != null) {
14627            app.waitDialog.dismiss();
14628            app.waitDialog = null;
14629        }
14630
14631        app.crashing = false;
14632        app.notResponding = false;
14633
14634        app.resetPackageList(mProcessStats);
14635        app.unlinkDeathRecipient();
14636        app.makeInactive(mProcessStats);
14637        app.waitingToKill = null;
14638        app.forcingToForeground = null;
14639        updateProcessForegroundLocked(app, false, false);
14640        app.foregroundActivities = false;
14641        app.hasShownUi = false;
14642        app.treatLikeActivity = false;
14643        app.hasAboveClient = false;
14644        app.hasClientActivities = false;
14645
14646        mServices.killServicesLocked(app, allowRestart);
14647
14648        boolean restart = false;
14649
14650        // Remove published content providers.
14651        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14652            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14653            final boolean always = app.bad || !allowRestart;
14654            if (removeDyingProviderLocked(app, cpr, always) || always) {
14655                // We left the provider in the launching list, need to
14656                // restart it.
14657                restart = true;
14658            }
14659
14660            cpr.provider = null;
14661            cpr.proc = null;
14662        }
14663        app.pubProviders.clear();
14664
14665        // Take care of any launching providers waiting for this process.
14666        if (checkAppInLaunchingProvidersLocked(app, false)) {
14667            restart = true;
14668        }
14669
14670        // Unregister from connected content providers.
14671        if (!app.conProviders.isEmpty()) {
14672            for (int i=0; i<app.conProviders.size(); i++) {
14673                ContentProviderConnection conn = app.conProviders.get(i);
14674                conn.provider.connections.remove(conn);
14675            }
14676            app.conProviders.clear();
14677        }
14678
14679        // At this point there may be remaining entries in mLaunchingProviders
14680        // where we were the only one waiting, so they are no longer of use.
14681        // Look for these and clean up if found.
14682        // XXX Commented out for now.  Trying to figure out a way to reproduce
14683        // the actual situation to identify what is actually going on.
14684        if (false) {
14685            for (int i=0; i<mLaunchingProviders.size(); i++) {
14686                ContentProviderRecord cpr = (ContentProviderRecord)
14687                        mLaunchingProviders.get(i);
14688                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14689                    synchronized (cpr) {
14690                        cpr.launchingApp = null;
14691                        cpr.notifyAll();
14692                    }
14693                }
14694            }
14695        }
14696
14697        skipCurrentReceiverLocked(app);
14698
14699        // Unregister any receivers.
14700        for (int i=app.receivers.size()-1; i>=0; i--) {
14701            removeReceiverLocked(app.receivers.valueAt(i));
14702        }
14703        app.receivers.clear();
14704
14705        // If the app is undergoing backup, tell the backup manager about it
14706        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14707            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14708                    + mBackupTarget.appInfo + " died during backup");
14709            try {
14710                IBackupManager bm = IBackupManager.Stub.asInterface(
14711                        ServiceManager.getService(Context.BACKUP_SERVICE));
14712                bm.agentDisconnected(app.info.packageName);
14713            } catch (RemoteException e) {
14714                // can't happen; backup manager is local
14715            }
14716        }
14717
14718        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14719            ProcessChangeItem item = mPendingProcessChanges.get(i);
14720            if (item.pid == app.pid) {
14721                mPendingProcessChanges.remove(i);
14722                mAvailProcessChanges.add(item);
14723            }
14724        }
14725        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14726
14727        // If the caller is restarting this app, then leave it in its
14728        // current lists and let the caller take care of it.
14729        if (restarting) {
14730            return false;
14731        }
14732
14733        if (!app.persistent || app.isolated) {
14734            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14735                    "Removing non-persistent process during cleanup: " + app);
14736            mProcessNames.remove(app.processName, app.uid);
14737            mIsolatedProcesses.remove(app.uid);
14738            if (mHeavyWeightProcess == app) {
14739                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14740                        mHeavyWeightProcess.userId, 0));
14741                mHeavyWeightProcess = null;
14742            }
14743        } else if (!app.removed) {
14744            // This app is persistent, so we need to keep its record around.
14745            // If it is not already on the pending app list, add it there
14746            // and start a new process for it.
14747            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14748                mPersistentStartingProcesses.add(app);
14749                restart = true;
14750            }
14751        }
14752        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14753                "Clean-up removing on hold: " + app);
14754        mProcessesOnHold.remove(app);
14755
14756        if (app == mHomeProcess) {
14757            mHomeProcess = null;
14758        }
14759        if (app == mPreviousProcess) {
14760            mPreviousProcess = null;
14761        }
14762
14763        if (restart && !app.isolated) {
14764            // We have components that still need to be running in the
14765            // process, so re-launch it.
14766            if (index < 0) {
14767                ProcessList.remove(app.pid);
14768            }
14769            mProcessNames.put(app.processName, app.uid, app);
14770            startProcessLocked(app, "restart", app.processName);
14771            return true;
14772        } else if (app.pid > 0 && app.pid != MY_PID) {
14773            // Goodbye!
14774            boolean removed;
14775            synchronized (mPidsSelfLocked) {
14776                mPidsSelfLocked.remove(app.pid);
14777                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14778            }
14779            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14780            if (app.isolated) {
14781                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14782            }
14783            app.setPid(0);
14784        }
14785        return false;
14786    }
14787
14788    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14789        // Look through the content providers we are waiting to have launched,
14790        // and if any run in this process then either schedule a restart of
14791        // the process or kill the client waiting for it if this process has
14792        // gone bad.
14793        int NL = mLaunchingProviders.size();
14794        boolean restart = false;
14795        for (int i=0; i<NL; i++) {
14796            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14797            if (cpr.launchingApp == app) {
14798                if (!alwaysBad && !app.bad) {
14799                    restart = true;
14800                } else {
14801                    removeDyingProviderLocked(app, cpr, true);
14802                    // cpr should have been removed from mLaunchingProviders
14803                    NL = mLaunchingProviders.size();
14804                    i--;
14805                }
14806            }
14807        }
14808        return restart;
14809    }
14810
14811    // =========================================================
14812    // SERVICES
14813    // =========================================================
14814
14815    @Override
14816    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14817            int flags) {
14818        enforceNotIsolatedCaller("getServices");
14819        synchronized (this) {
14820            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14821        }
14822    }
14823
14824    @Override
14825    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14826        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14827        synchronized (this) {
14828            return mServices.getRunningServiceControlPanelLocked(name);
14829        }
14830    }
14831
14832    @Override
14833    public ComponentName startService(IApplicationThread caller, Intent service,
14834            String resolvedType, int userId) {
14835        enforceNotIsolatedCaller("startService");
14836        // Refuse possible leaked file descriptors
14837        if (service != null && service.hasFileDescriptors() == true) {
14838            throw new IllegalArgumentException("File descriptors passed in Intent");
14839        }
14840
14841        if (DEBUG_SERVICE)
14842            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14843        synchronized(this) {
14844            final int callingPid = Binder.getCallingPid();
14845            final int callingUid = Binder.getCallingUid();
14846            final long origId = Binder.clearCallingIdentity();
14847            ComponentName res = mServices.startServiceLocked(caller, service,
14848                    resolvedType, callingPid, callingUid, userId);
14849            Binder.restoreCallingIdentity(origId);
14850            return res;
14851        }
14852    }
14853
14854    ComponentName startServiceInPackage(int uid,
14855            Intent service, String resolvedType, int userId) {
14856        synchronized(this) {
14857            if (DEBUG_SERVICE)
14858                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14859            final long origId = Binder.clearCallingIdentity();
14860            ComponentName res = mServices.startServiceLocked(null, service,
14861                    resolvedType, -1, uid, userId);
14862            Binder.restoreCallingIdentity(origId);
14863            return res;
14864        }
14865    }
14866
14867    @Override
14868    public int stopService(IApplicationThread caller, Intent service,
14869            String resolvedType, int userId) {
14870        enforceNotIsolatedCaller("stopService");
14871        // Refuse possible leaked file descriptors
14872        if (service != null && service.hasFileDescriptors() == true) {
14873            throw new IllegalArgumentException("File descriptors passed in Intent");
14874        }
14875
14876        synchronized(this) {
14877            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14878        }
14879    }
14880
14881    @Override
14882    public IBinder peekService(Intent service, String resolvedType) {
14883        enforceNotIsolatedCaller("peekService");
14884        // Refuse possible leaked file descriptors
14885        if (service != null && service.hasFileDescriptors() == true) {
14886            throw new IllegalArgumentException("File descriptors passed in Intent");
14887        }
14888        synchronized(this) {
14889            return mServices.peekServiceLocked(service, resolvedType);
14890        }
14891    }
14892
14893    @Override
14894    public boolean stopServiceToken(ComponentName className, IBinder token,
14895            int startId) {
14896        synchronized(this) {
14897            return mServices.stopServiceTokenLocked(className, token, startId);
14898        }
14899    }
14900
14901    @Override
14902    public void setServiceForeground(ComponentName className, IBinder token,
14903            int id, Notification notification, boolean removeNotification) {
14904        synchronized(this) {
14905            mServices.setServiceForegroundLocked(className, token, id, notification,
14906                    removeNotification);
14907        }
14908    }
14909
14910    @Override
14911    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14912            boolean requireFull, String name, String callerPackage) {
14913        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14914                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14915    }
14916
14917    int unsafeConvertIncomingUser(int userId) {
14918        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14919                ? mCurrentUserId : userId;
14920    }
14921
14922    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14923            int allowMode, String name, String callerPackage) {
14924        final int callingUserId = UserHandle.getUserId(callingUid);
14925        if (callingUserId == userId) {
14926            return userId;
14927        }
14928
14929        // Note that we may be accessing mCurrentUserId outside of a lock...
14930        // shouldn't be a big deal, if this is being called outside
14931        // of a locked context there is intrinsically a race with
14932        // the value the caller will receive and someone else changing it.
14933        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14934        // we will switch to the calling user if access to the current user fails.
14935        int targetUserId = unsafeConvertIncomingUser(userId);
14936
14937        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14938            final boolean allow;
14939            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14940                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14941                // If the caller has this permission, they always pass go.  And collect $200.
14942                allow = true;
14943            } else if (allowMode == ALLOW_FULL_ONLY) {
14944                // We require full access, sucks to be you.
14945                allow = false;
14946            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14947                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14948                // If the caller does not have either permission, they are always doomed.
14949                allow = false;
14950            } else if (allowMode == ALLOW_NON_FULL) {
14951                // We are blanket allowing non-full access, you lucky caller!
14952                allow = true;
14953            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14954                // We may or may not allow this depending on whether the two users are
14955                // in the same profile.
14956                synchronized (mUserProfileGroupIdsSelfLocked) {
14957                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14958                            UserInfo.NO_PROFILE_GROUP_ID);
14959                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14960                            UserInfo.NO_PROFILE_GROUP_ID);
14961                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14962                            && callingProfile == targetProfile;
14963                }
14964            } else {
14965                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14966            }
14967            if (!allow) {
14968                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14969                    // In this case, they would like to just execute as their
14970                    // owner user instead of failing.
14971                    targetUserId = callingUserId;
14972                } else {
14973                    StringBuilder builder = new StringBuilder(128);
14974                    builder.append("Permission Denial: ");
14975                    builder.append(name);
14976                    if (callerPackage != null) {
14977                        builder.append(" from ");
14978                        builder.append(callerPackage);
14979                    }
14980                    builder.append(" asks to run as user ");
14981                    builder.append(userId);
14982                    builder.append(" but is calling from user ");
14983                    builder.append(UserHandle.getUserId(callingUid));
14984                    builder.append("; this requires ");
14985                    builder.append(INTERACT_ACROSS_USERS_FULL);
14986                    if (allowMode != ALLOW_FULL_ONLY) {
14987                        builder.append(" or ");
14988                        builder.append(INTERACT_ACROSS_USERS);
14989                    }
14990                    String msg = builder.toString();
14991                    Slog.w(TAG, msg);
14992                    throw new SecurityException(msg);
14993                }
14994            }
14995        }
14996        if (!allowAll && targetUserId < 0) {
14997            throw new IllegalArgumentException(
14998                    "Call does not support special user #" + targetUserId);
14999        }
15000        // Check shell permission
15001        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15002            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15003                    targetUserId)) {
15004                throw new SecurityException("Shell does not have permission to access user "
15005                        + targetUserId + "\n " + Debug.getCallers(3));
15006            }
15007        }
15008        return targetUserId;
15009    }
15010
15011    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15012            String className, int flags) {
15013        boolean result = false;
15014        // For apps that don't have pre-defined UIDs, check for permission
15015        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15016            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15017                if (ActivityManager.checkUidPermission(
15018                        INTERACT_ACROSS_USERS,
15019                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15020                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15021                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15022                            + " requests FLAG_SINGLE_USER, but app does not hold "
15023                            + INTERACT_ACROSS_USERS;
15024                    Slog.w(TAG, msg);
15025                    throw new SecurityException(msg);
15026                }
15027                // Permission passed
15028                result = true;
15029            }
15030        } else if ("system".equals(componentProcessName)) {
15031            result = true;
15032        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15033            // Phone app and persistent apps are allowed to export singleuser providers.
15034            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15035                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15036        }
15037        if (DEBUG_MU) {
15038            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15039                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15040        }
15041        return result;
15042    }
15043
15044    /**
15045     * Checks to see if the caller is in the same app as the singleton
15046     * component, or the component is in a special app. It allows special apps
15047     * to export singleton components but prevents exporting singleton
15048     * components for regular apps.
15049     */
15050    boolean isValidSingletonCall(int callingUid, int componentUid) {
15051        int componentAppId = UserHandle.getAppId(componentUid);
15052        return UserHandle.isSameApp(callingUid, componentUid)
15053                || componentAppId == Process.SYSTEM_UID
15054                || componentAppId == Process.PHONE_UID
15055                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15056                        == PackageManager.PERMISSION_GRANTED;
15057    }
15058
15059    public int bindService(IApplicationThread caller, IBinder token,
15060            Intent service, String resolvedType,
15061            IServiceConnection connection, int flags, int userId) {
15062        enforceNotIsolatedCaller("bindService");
15063
15064        // Refuse possible leaked file descriptors
15065        if (service != null && service.hasFileDescriptors() == true) {
15066            throw new IllegalArgumentException("File descriptors passed in Intent");
15067        }
15068
15069        synchronized(this) {
15070            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15071                    connection, flags, userId);
15072        }
15073    }
15074
15075    public boolean unbindService(IServiceConnection connection) {
15076        synchronized (this) {
15077            return mServices.unbindServiceLocked(connection);
15078        }
15079    }
15080
15081    public void publishService(IBinder token, Intent intent, IBinder service) {
15082        // Refuse possible leaked file descriptors
15083        if (intent != null && intent.hasFileDescriptors() == true) {
15084            throw new IllegalArgumentException("File descriptors passed in Intent");
15085        }
15086
15087        synchronized(this) {
15088            if (!(token instanceof ServiceRecord)) {
15089                throw new IllegalArgumentException("Invalid service token");
15090            }
15091            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15092        }
15093    }
15094
15095    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15096        // Refuse possible leaked file descriptors
15097        if (intent != null && intent.hasFileDescriptors() == true) {
15098            throw new IllegalArgumentException("File descriptors passed in Intent");
15099        }
15100
15101        synchronized(this) {
15102            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15103        }
15104    }
15105
15106    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15107        synchronized(this) {
15108            if (!(token instanceof ServiceRecord)) {
15109                throw new IllegalArgumentException("Invalid service token");
15110            }
15111            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15112        }
15113    }
15114
15115    // =========================================================
15116    // BACKUP AND RESTORE
15117    // =========================================================
15118
15119    // Cause the target app to be launched if necessary and its backup agent
15120    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15121    // activity manager to announce its creation.
15122    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15123        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15124        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15125
15126        synchronized(this) {
15127            // !!! TODO: currently no check here that we're already bound
15128            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15129            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15130            synchronized (stats) {
15131                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15132            }
15133
15134            // Backup agent is now in use, its package can't be stopped.
15135            try {
15136                AppGlobals.getPackageManager().setPackageStoppedState(
15137                        app.packageName, false, UserHandle.getUserId(app.uid));
15138            } catch (RemoteException e) {
15139            } catch (IllegalArgumentException e) {
15140                Slog.w(TAG, "Failed trying to unstop package "
15141                        + app.packageName + ": " + e);
15142            }
15143
15144            BackupRecord r = new BackupRecord(ss, app, backupMode);
15145            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15146                    ? new ComponentName(app.packageName, app.backupAgentName)
15147                    : new ComponentName("android", "FullBackupAgent");
15148            // startProcessLocked() returns existing proc's record if it's already running
15149            ProcessRecord proc = startProcessLocked(app.processName, app,
15150                    false, 0, "backup", hostingName, false, false, false);
15151            if (proc == null) {
15152                Slog.e(TAG, "Unable to start backup agent process " + r);
15153                return false;
15154            }
15155
15156            r.app = proc;
15157            mBackupTarget = r;
15158            mBackupAppName = app.packageName;
15159
15160            // Try not to kill the process during backup
15161            updateOomAdjLocked(proc);
15162
15163            // If the process is already attached, schedule the creation of the backup agent now.
15164            // If it is not yet live, this will be done when it attaches to the framework.
15165            if (proc.thread != null) {
15166                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15167                try {
15168                    proc.thread.scheduleCreateBackupAgent(app,
15169                            compatibilityInfoForPackageLocked(app), backupMode);
15170                } catch (RemoteException e) {
15171                    // Will time out on the backup manager side
15172                }
15173            } else {
15174                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15175            }
15176            // Invariants: at this point, the target app process exists and the application
15177            // is either already running or in the process of coming up.  mBackupTarget and
15178            // mBackupAppName describe the app, so that when it binds back to the AM we
15179            // know that it's scheduled for a backup-agent operation.
15180        }
15181
15182        return true;
15183    }
15184
15185    @Override
15186    public void clearPendingBackup() {
15187        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15188        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15189
15190        synchronized (this) {
15191            mBackupTarget = null;
15192            mBackupAppName = null;
15193        }
15194    }
15195
15196    // A backup agent has just come up
15197    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15198        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15199                + " = " + agent);
15200
15201        synchronized(this) {
15202            if (!agentPackageName.equals(mBackupAppName)) {
15203                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15204                return;
15205            }
15206        }
15207
15208        long oldIdent = Binder.clearCallingIdentity();
15209        try {
15210            IBackupManager bm = IBackupManager.Stub.asInterface(
15211                    ServiceManager.getService(Context.BACKUP_SERVICE));
15212            bm.agentConnected(agentPackageName, agent);
15213        } catch (RemoteException e) {
15214            // can't happen; the backup manager service is local
15215        } catch (Exception e) {
15216            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15217            e.printStackTrace();
15218        } finally {
15219            Binder.restoreCallingIdentity(oldIdent);
15220        }
15221    }
15222
15223    // done with this agent
15224    public void unbindBackupAgent(ApplicationInfo appInfo) {
15225        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15226        if (appInfo == null) {
15227            Slog.w(TAG, "unbind backup agent for null app");
15228            return;
15229        }
15230
15231        synchronized(this) {
15232            try {
15233                if (mBackupAppName == null) {
15234                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15235                    return;
15236                }
15237
15238                if (!mBackupAppName.equals(appInfo.packageName)) {
15239                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15240                    return;
15241                }
15242
15243                // Not backing this app up any more; reset its OOM adjustment
15244                final ProcessRecord proc = mBackupTarget.app;
15245                updateOomAdjLocked(proc);
15246
15247                // If the app crashed during backup, 'thread' will be null here
15248                if (proc.thread != null) {
15249                    try {
15250                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15251                                compatibilityInfoForPackageLocked(appInfo));
15252                    } catch (Exception e) {
15253                        Slog.e(TAG, "Exception when unbinding backup agent:");
15254                        e.printStackTrace();
15255                    }
15256                }
15257            } finally {
15258                mBackupTarget = null;
15259                mBackupAppName = null;
15260            }
15261        }
15262    }
15263    // =========================================================
15264    // BROADCASTS
15265    // =========================================================
15266
15267    private final List getStickiesLocked(String action, IntentFilter filter,
15268            List cur, int userId) {
15269        final ContentResolver resolver = mContext.getContentResolver();
15270        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15271        if (stickies == null) {
15272            return cur;
15273        }
15274        final ArrayList<Intent> list = stickies.get(action);
15275        if (list == null) {
15276            return cur;
15277        }
15278        int N = list.size();
15279        for (int i=0; i<N; i++) {
15280            Intent intent = list.get(i);
15281            if (filter.match(resolver, intent, true, TAG) >= 0) {
15282                if (cur == null) {
15283                    cur = new ArrayList<Intent>();
15284                }
15285                cur.add(intent);
15286            }
15287        }
15288        return cur;
15289    }
15290
15291    boolean isPendingBroadcastProcessLocked(int pid) {
15292        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15293                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15294    }
15295
15296    void skipPendingBroadcastLocked(int pid) {
15297            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15298            for (BroadcastQueue queue : mBroadcastQueues) {
15299                queue.skipPendingBroadcastLocked(pid);
15300            }
15301    }
15302
15303    // The app just attached; send any pending broadcasts that it should receive
15304    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15305        boolean didSomething = false;
15306        for (BroadcastQueue queue : mBroadcastQueues) {
15307            didSomething |= queue.sendPendingBroadcastsLocked(app);
15308        }
15309        return didSomething;
15310    }
15311
15312    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15313            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15314        enforceNotIsolatedCaller("registerReceiver");
15315        int callingUid;
15316        int callingPid;
15317        synchronized(this) {
15318            ProcessRecord callerApp = null;
15319            if (caller != null) {
15320                callerApp = getRecordForAppLocked(caller);
15321                if (callerApp == null) {
15322                    throw new SecurityException(
15323                            "Unable to find app for caller " + caller
15324                            + " (pid=" + Binder.getCallingPid()
15325                            + ") when registering receiver " + receiver);
15326                }
15327                if (callerApp.info.uid != Process.SYSTEM_UID &&
15328                        !callerApp.pkgList.containsKey(callerPackage) &&
15329                        !"android".equals(callerPackage)) {
15330                    throw new SecurityException("Given caller package " + callerPackage
15331                            + " is not running in process " + callerApp);
15332                }
15333                callingUid = callerApp.info.uid;
15334                callingPid = callerApp.pid;
15335            } else {
15336                callerPackage = null;
15337                callingUid = Binder.getCallingUid();
15338                callingPid = Binder.getCallingPid();
15339            }
15340
15341            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15342                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15343
15344            List allSticky = null;
15345
15346            // Look for any matching sticky broadcasts...
15347            Iterator actions = filter.actionsIterator();
15348            if (actions != null) {
15349                while (actions.hasNext()) {
15350                    String action = (String)actions.next();
15351                    allSticky = getStickiesLocked(action, filter, allSticky,
15352                            UserHandle.USER_ALL);
15353                    allSticky = getStickiesLocked(action, filter, allSticky,
15354                            UserHandle.getUserId(callingUid));
15355                }
15356            } else {
15357                allSticky = getStickiesLocked(null, filter, allSticky,
15358                        UserHandle.USER_ALL);
15359                allSticky = getStickiesLocked(null, filter, allSticky,
15360                        UserHandle.getUserId(callingUid));
15361            }
15362
15363            // The first sticky in the list is returned directly back to
15364            // the client.
15365            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15366
15367            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15368                    + ": " + sticky);
15369
15370            if (receiver == null) {
15371                return sticky;
15372            }
15373
15374            ReceiverList rl
15375                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15376            if (rl == null) {
15377                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15378                        userId, receiver);
15379                if (rl.app != null) {
15380                    rl.app.receivers.add(rl);
15381                } else {
15382                    try {
15383                        receiver.asBinder().linkToDeath(rl, 0);
15384                    } catch (RemoteException e) {
15385                        return sticky;
15386                    }
15387                    rl.linkedToDeath = true;
15388                }
15389                mRegisteredReceivers.put(receiver.asBinder(), rl);
15390            } else if (rl.uid != callingUid) {
15391                throw new IllegalArgumentException(
15392                        "Receiver requested to register for uid " + callingUid
15393                        + " was previously registered for uid " + rl.uid);
15394            } else if (rl.pid != callingPid) {
15395                throw new IllegalArgumentException(
15396                        "Receiver requested to register for pid " + callingPid
15397                        + " was previously registered for pid " + rl.pid);
15398            } else if (rl.userId != userId) {
15399                throw new IllegalArgumentException(
15400                        "Receiver requested to register for user " + userId
15401                        + " was previously registered for user " + rl.userId);
15402            }
15403            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15404                    permission, callingUid, userId);
15405            rl.add(bf);
15406            if (!bf.debugCheck()) {
15407                Slog.w(TAG, "==> For Dynamic broadast");
15408            }
15409            mReceiverResolver.addFilter(bf);
15410
15411            // Enqueue broadcasts for all existing stickies that match
15412            // this filter.
15413            if (allSticky != null) {
15414                ArrayList receivers = new ArrayList();
15415                receivers.add(bf);
15416
15417                int N = allSticky.size();
15418                for (int i=0; i<N; i++) {
15419                    Intent intent = (Intent)allSticky.get(i);
15420                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15421                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15422                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15423                            null, null, false, true, true, -1);
15424                    queue.enqueueParallelBroadcastLocked(r);
15425                    queue.scheduleBroadcastsLocked();
15426                }
15427            }
15428
15429            return sticky;
15430        }
15431    }
15432
15433    public void unregisterReceiver(IIntentReceiver receiver) {
15434        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15435
15436        final long origId = Binder.clearCallingIdentity();
15437        try {
15438            boolean doTrim = false;
15439
15440            synchronized(this) {
15441                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15442                if (rl != null) {
15443                    if (rl.curBroadcast != null) {
15444                        BroadcastRecord r = rl.curBroadcast;
15445                        final boolean doNext = finishReceiverLocked(
15446                                receiver.asBinder(), r.resultCode, r.resultData,
15447                                r.resultExtras, r.resultAbort);
15448                        if (doNext) {
15449                            doTrim = true;
15450                            r.queue.processNextBroadcast(false);
15451                        }
15452                    }
15453
15454                    if (rl.app != null) {
15455                        rl.app.receivers.remove(rl);
15456                    }
15457                    removeReceiverLocked(rl);
15458                    if (rl.linkedToDeath) {
15459                        rl.linkedToDeath = false;
15460                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15461                    }
15462                }
15463            }
15464
15465            // If we actually concluded any broadcasts, we might now be able
15466            // to trim the recipients' apps from our working set
15467            if (doTrim) {
15468                trimApplications();
15469                return;
15470            }
15471
15472        } finally {
15473            Binder.restoreCallingIdentity(origId);
15474        }
15475    }
15476
15477    void removeReceiverLocked(ReceiverList rl) {
15478        mRegisteredReceivers.remove(rl.receiver.asBinder());
15479        int N = rl.size();
15480        for (int i=0; i<N; i++) {
15481            mReceiverResolver.removeFilter(rl.get(i));
15482        }
15483    }
15484
15485    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15486        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15487            ProcessRecord r = mLruProcesses.get(i);
15488            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15489                try {
15490                    r.thread.dispatchPackageBroadcast(cmd, packages);
15491                } catch (RemoteException ex) {
15492                }
15493            }
15494        }
15495    }
15496
15497    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15498            int callingUid, int[] users) {
15499        List<ResolveInfo> receivers = null;
15500        try {
15501            HashSet<ComponentName> singleUserReceivers = null;
15502            boolean scannedFirstReceivers = false;
15503            for (int user : users) {
15504                // Skip users that have Shell restrictions
15505                if (callingUid == Process.SHELL_UID
15506                        && getUserManagerLocked().hasUserRestriction(
15507                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15508                    continue;
15509                }
15510                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15511                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15512                if (user != 0 && newReceivers != null) {
15513                    // If this is not the primary user, we need to check for
15514                    // any receivers that should be filtered out.
15515                    for (int i=0; i<newReceivers.size(); i++) {
15516                        ResolveInfo ri = newReceivers.get(i);
15517                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15518                            newReceivers.remove(i);
15519                            i--;
15520                        }
15521                    }
15522                }
15523                if (newReceivers != null && newReceivers.size() == 0) {
15524                    newReceivers = null;
15525                }
15526                if (receivers == null) {
15527                    receivers = newReceivers;
15528                } else if (newReceivers != null) {
15529                    // We need to concatenate the additional receivers
15530                    // found with what we have do far.  This would be easy,
15531                    // but we also need to de-dup any receivers that are
15532                    // singleUser.
15533                    if (!scannedFirstReceivers) {
15534                        // Collect any single user receivers we had already retrieved.
15535                        scannedFirstReceivers = true;
15536                        for (int i=0; i<receivers.size(); i++) {
15537                            ResolveInfo ri = receivers.get(i);
15538                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15539                                ComponentName cn = new ComponentName(
15540                                        ri.activityInfo.packageName, ri.activityInfo.name);
15541                                if (singleUserReceivers == null) {
15542                                    singleUserReceivers = new HashSet<ComponentName>();
15543                                }
15544                                singleUserReceivers.add(cn);
15545                            }
15546                        }
15547                    }
15548                    // Add the new results to the existing results, tracking
15549                    // and de-dupping single user receivers.
15550                    for (int i=0; i<newReceivers.size(); i++) {
15551                        ResolveInfo ri = newReceivers.get(i);
15552                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15553                            ComponentName cn = new ComponentName(
15554                                    ri.activityInfo.packageName, ri.activityInfo.name);
15555                            if (singleUserReceivers == null) {
15556                                singleUserReceivers = new HashSet<ComponentName>();
15557                            }
15558                            if (!singleUserReceivers.contains(cn)) {
15559                                singleUserReceivers.add(cn);
15560                                receivers.add(ri);
15561                            }
15562                        } else {
15563                            receivers.add(ri);
15564                        }
15565                    }
15566                }
15567            }
15568        } catch (RemoteException ex) {
15569            // pm is in same process, this will never happen.
15570        }
15571        return receivers;
15572    }
15573
15574    private final int broadcastIntentLocked(ProcessRecord callerApp,
15575            String callerPackage, Intent intent, String resolvedType,
15576            IIntentReceiver resultTo, int resultCode, String resultData,
15577            Bundle map, String requiredPermission, int appOp,
15578            boolean ordered, boolean sticky, int callingPid, int callingUid,
15579            int userId) {
15580        intent = new Intent(intent);
15581
15582        // By default broadcasts do not go to stopped apps.
15583        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15584
15585        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15586            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15587            + " ordered=" + ordered + " userid=" + userId);
15588        if ((resultTo != null) && !ordered) {
15589            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15590        }
15591
15592        userId = handleIncomingUser(callingPid, callingUid, userId,
15593                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15594
15595        // Make sure that the user who is receiving this broadcast is started.
15596        // If not, we will just skip it.
15597
15598        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15599            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15600                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15601                Slog.w(TAG, "Skipping broadcast of " + intent
15602                        + ": user " + userId + " is stopped");
15603                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15604            }
15605        }
15606
15607        /*
15608         * Prevent non-system code (defined here to be non-persistent
15609         * processes) from sending protected broadcasts.
15610         */
15611        int callingAppId = UserHandle.getAppId(callingUid);
15612        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15613            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15614            || callingAppId == Process.NFC_UID || callingUid == 0) {
15615            // Always okay.
15616        } else if (callerApp == null || !callerApp.persistent) {
15617            try {
15618                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15619                        intent.getAction())) {
15620                    String msg = "Permission Denial: not allowed to send broadcast "
15621                            + intent.getAction() + " from pid="
15622                            + callingPid + ", uid=" + callingUid;
15623                    Slog.w(TAG, msg);
15624                    throw new SecurityException(msg);
15625                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15626                    // Special case for compatibility: we don't want apps to send this,
15627                    // but historically it has not been protected and apps may be using it
15628                    // to poke their own app widget.  So, instead of making it protected,
15629                    // just limit it to the caller.
15630                    if (callerApp == null) {
15631                        String msg = "Permission Denial: not allowed to send broadcast "
15632                                + intent.getAction() + " from unknown caller.";
15633                        Slog.w(TAG, msg);
15634                        throw new SecurityException(msg);
15635                    } else if (intent.getComponent() != null) {
15636                        // They are good enough to send to an explicit component...  verify
15637                        // it is being sent to the calling app.
15638                        if (!intent.getComponent().getPackageName().equals(
15639                                callerApp.info.packageName)) {
15640                            String msg = "Permission Denial: not allowed to send broadcast "
15641                                    + intent.getAction() + " to "
15642                                    + intent.getComponent().getPackageName() + " from "
15643                                    + callerApp.info.packageName;
15644                            Slog.w(TAG, msg);
15645                            throw new SecurityException(msg);
15646                        }
15647                    } else {
15648                        // Limit broadcast to their own package.
15649                        intent.setPackage(callerApp.info.packageName);
15650                    }
15651                }
15652            } catch (RemoteException e) {
15653                Slog.w(TAG, "Remote exception", e);
15654                return ActivityManager.BROADCAST_SUCCESS;
15655            }
15656        }
15657
15658        final String action = intent.getAction();
15659        if (action != null) {
15660            switch (action) {
15661                case Intent.ACTION_UID_REMOVED:
15662                case Intent.ACTION_PACKAGE_REMOVED:
15663                case Intent.ACTION_PACKAGE_CHANGED:
15664                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15665                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15666                    // Handle special intents: if this broadcast is from the package
15667                    // manager about a package being removed, we need to remove all of
15668                    // its activities from the history stack.
15669                    if (checkComponentPermission(
15670                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15671                            callingPid, callingUid, -1, true)
15672                            != PackageManager.PERMISSION_GRANTED) {
15673                        String msg = "Permission Denial: " + intent.getAction()
15674                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15675                                + ", uid=" + callingUid + ")"
15676                                + " requires "
15677                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15678                        Slog.w(TAG, msg);
15679                        throw new SecurityException(msg);
15680                    }
15681                    switch (action) {
15682                        case Intent.ACTION_UID_REMOVED:
15683                            final Bundle intentExtras = intent.getExtras();
15684                            final int uid = intentExtras != null
15685                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15686                            if (uid >= 0) {
15687                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15688                                synchronized (bs) {
15689                                    bs.removeUidStatsLocked(uid);
15690                                }
15691                                mAppOpsService.uidRemoved(uid);
15692                            }
15693                            break;
15694                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15695                            // If resources are unavailable just force stop all those packages
15696                            // and flush the attribute cache as well.
15697                            String list[] =
15698                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15699                            if (list != null && list.length > 0) {
15700                                for (int i = 0; i < list.length; i++) {
15701                                    forceStopPackageLocked(list[i], -1, false, true, true,
15702                                            false, false, userId, "storage unmount");
15703                                }
15704                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15705                                sendPackageBroadcastLocked(
15706                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15707                                        userId);
15708                            }
15709                            break;
15710                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15711                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15712                            break;
15713                        case Intent.ACTION_PACKAGE_REMOVED:
15714                        case Intent.ACTION_PACKAGE_CHANGED:
15715                            Uri data = intent.getData();
15716                            String ssp;
15717                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15718                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15719                                boolean fullUninstall = removed &&
15720                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15721                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15722                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15723                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15724                                            false, true, true, false, fullUninstall, userId,
15725                                            removed ? "pkg removed" : "pkg changed");
15726                                }
15727                                if (removed) {
15728                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15729                                            new String[] {ssp}, userId);
15730                                    if (fullUninstall) {
15731                                        mAppOpsService.packageRemoved(
15732                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15733
15734                                        // Remove all permissions granted from/to this package
15735                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15736
15737                                        removeTasksByPackageNameLocked(ssp, userId);
15738                                    }
15739                                } else {
15740                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15741                                }
15742                            }
15743                            break;
15744                    }
15745                    break;
15746                case Intent.ACTION_PACKAGE_ADDED:
15747                    // Special case for adding a package: by default turn on compatibility mode.
15748                    Uri data = intent.getData();
15749                    String ssp;
15750                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15751                        final boolean replacing =
15752                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15753                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15754
15755                        if (replacing) {
15756                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15757                        }
15758                    }
15759                    break;
15760                case Intent.ACTION_TIMEZONE_CHANGED:
15761                    // If this is the time zone changed action, queue up a message that will reset
15762                    // the timezone of all currently running processes. This message will get
15763                    // queued up before the broadcast happens.
15764                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15765                    break;
15766                case Intent.ACTION_TIME_CHANGED:
15767                    // If the user set the time, let all running processes know.
15768                    final int is24Hour =
15769                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15770                                    : 0;
15771                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15772                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15773                    synchronized (stats) {
15774                        stats.noteCurrentTimeChangedLocked();
15775                    }
15776                    break;
15777                case Intent.ACTION_CLEAR_DNS_CACHE:
15778                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15779                    break;
15780                case Proxy.PROXY_CHANGE_ACTION:
15781                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15782                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15783                    break;
15784            }
15785        }
15786
15787        // Add to the sticky list if requested.
15788        if (sticky) {
15789            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15790                    callingPid, callingUid)
15791                    != PackageManager.PERMISSION_GRANTED) {
15792                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15793                        + callingPid + ", uid=" + callingUid
15794                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15795                Slog.w(TAG, msg);
15796                throw new SecurityException(msg);
15797            }
15798            if (requiredPermission != null) {
15799                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15800                        + " and enforce permission " + requiredPermission);
15801                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15802            }
15803            if (intent.getComponent() != null) {
15804                throw new SecurityException(
15805                        "Sticky broadcasts can't target a specific component");
15806            }
15807            // We use userId directly here, since the "all" target is maintained
15808            // as a separate set of sticky broadcasts.
15809            if (userId != UserHandle.USER_ALL) {
15810                // But first, if this is not a broadcast to all users, then
15811                // make sure it doesn't conflict with an existing broadcast to
15812                // all users.
15813                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15814                        UserHandle.USER_ALL);
15815                if (stickies != null) {
15816                    ArrayList<Intent> list = stickies.get(intent.getAction());
15817                    if (list != null) {
15818                        int N = list.size();
15819                        int i;
15820                        for (i=0; i<N; i++) {
15821                            if (intent.filterEquals(list.get(i))) {
15822                                throw new IllegalArgumentException(
15823                                        "Sticky broadcast " + intent + " for user "
15824                                        + userId + " conflicts with existing global broadcast");
15825                            }
15826                        }
15827                    }
15828                }
15829            }
15830            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15831            if (stickies == null) {
15832                stickies = new ArrayMap<String, ArrayList<Intent>>();
15833                mStickyBroadcasts.put(userId, stickies);
15834            }
15835            ArrayList<Intent> list = stickies.get(intent.getAction());
15836            if (list == null) {
15837                list = new ArrayList<Intent>();
15838                stickies.put(intent.getAction(), list);
15839            }
15840            int N = list.size();
15841            int i;
15842            for (i=0; i<N; i++) {
15843                if (intent.filterEquals(list.get(i))) {
15844                    // This sticky already exists, replace it.
15845                    list.set(i, new Intent(intent));
15846                    break;
15847                }
15848            }
15849            if (i >= N) {
15850                list.add(new Intent(intent));
15851            }
15852        }
15853
15854        int[] users;
15855        if (userId == UserHandle.USER_ALL) {
15856            // Caller wants broadcast to go to all started users.
15857            users = mStartedUserArray;
15858        } else {
15859            // Caller wants broadcast to go to one specific user.
15860            users = new int[] {userId};
15861        }
15862
15863        // Figure out who all will receive this broadcast.
15864        List receivers = null;
15865        List<BroadcastFilter> registeredReceivers = null;
15866        // Need to resolve the intent to interested receivers...
15867        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15868                 == 0) {
15869            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15870        }
15871        if (intent.getComponent() == null) {
15872            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15873                // Query one target user at a time, excluding shell-restricted users
15874                UserManagerService ums = getUserManagerLocked();
15875                for (int i = 0; i < users.length; i++) {
15876                    if (ums.hasUserRestriction(
15877                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15878                        continue;
15879                    }
15880                    List<BroadcastFilter> registeredReceiversForUser =
15881                            mReceiverResolver.queryIntent(intent,
15882                                    resolvedType, false, users[i]);
15883                    if (registeredReceivers == null) {
15884                        registeredReceivers = registeredReceiversForUser;
15885                    } else if (registeredReceiversForUser != null) {
15886                        registeredReceivers.addAll(registeredReceiversForUser);
15887                    }
15888                }
15889            } else {
15890                registeredReceivers = mReceiverResolver.queryIntent(intent,
15891                        resolvedType, false, userId);
15892            }
15893        }
15894
15895        final boolean replacePending =
15896                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15897
15898        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15899                + " replacePending=" + replacePending);
15900
15901        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15902        if (!ordered && NR > 0) {
15903            // If we are not serializing this broadcast, then send the
15904            // registered receivers separately so they don't wait for the
15905            // components to be launched.
15906            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15907            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15908                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15909                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15910                    ordered, sticky, false, userId);
15911            if (DEBUG_BROADCAST) Slog.v(
15912                    TAG, "Enqueueing parallel broadcast " + r);
15913            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15914            if (!replaced) {
15915                queue.enqueueParallelBroadcastLocked(r);
15916                queue.scheduleBroadcastsLocked();
15917            }
15918            registeredReceivers = null;
15919            NR = 0;
15920        }
15921
15922        // Merge into one list.
15923        int ir = 0;
15924        if (receivers != null) {
15925            // A special case for PACKAGE_ADDED: do not allow the package
15926            // being added to see this broadcast.  This prevents them from
15927            // using this as a back door to get run as soon as they are
15928            // installed.  Maybe in the future we want to have a special install
15929            // broadcast or such for apps, but we'd like to deliberately make
15930            // this decision.
15931            String skipPackages[] = null;
15932            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15933                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15934                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15935                Uri data = intent.getData();
15936                if (data != null) {
15937                    String pkgName = data.getSchemeSpecificPart();
15938                    if (pkgName != null) {
15939                        skipPackages = new String[] { pkgName };
15940                    }
15941                }
15942            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15943                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15944            }
15945            if (skipPackages != null && (skipPackages.length > 0)) {
15946                for (String skipPackage : skipPackages) {
15947                    if (skipPackage != null) {
15948                        int NT = receivers.size();
15949                        for (int it=0; it<NT; it++) {
15950                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15951                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15952                                receivers.remove(it);
15953                                it--;
15954                                NT--;
15955                            }
15956                        }
15957                    }
15958                }
15959            }
15960
15961            int NT = receivers != null ? receivers.size() : 0;
15962            int it = 0;
15963            ResolveInfo curt = null;
15964            BroadcastFilter curr = null;
15965            while (it < NT && ir < NR) {
15966                if (curt == null) {
15967                    curt = (ResolveInfo)receivers.get(it);
15968                }
15969                if (curr == null) {
15970                    curr = registeredReceivers.get(ir);
15971                }
15972                if (curr.getPriority() >= curt.priority) {
15973                    // Insert this broadcast record into the final list.
15974                    receivers.add(it, curr);
15975                    ir++;
15976                    curr = null;
15977                    it++;
15978                    NT++;
15979                } else {
15980                    // Skip to the next ResolveInfo in the final list.
15981                    it++;
15982                    curt = null;
15983                }
15984            }
15985        }
15986        while (ir < NR) {
15987            if (receivers == null) {
15988                receivers = new ArrayList();
15989            }
15990            receivers.add(registeredReceivers.get(ir));
15991            ir++;
15992        }
15993
15994        if ((receivers != null && receivers.size() > 0)
15995                || resultTo != null) {
15996            BroadcastQueue queue = broadcastQueueForIntent(intent);
15997            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15998                    callerPackage, callingPid, callingUid, resolvedType,
15999                    requiredPermission, appOp, receivers, resultTo, resultCode,
16000                    resultData, map, ordered, sticky, false, userId);
16001            if (DEBUG_BROADCAST) Slog.v(
16002                    TAG, "Enqueueing ordered broadcast " + r
16003                    + ": prev had " + queue.mOrderedBroadcasts.size());
16004            if (DEBUG_BROADCAST) {
16005                int seq = r.intent.getIntExtra("seq", -1);
16006                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16007            }
16008            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16009            if (!replaced) {
16010                queue.enqueueOrderedBroadcastLocked(r);
16011                queue.scheduleBroadcastsLocked();
16012            }
16013        }
16014
16015        return ActivityManager.BROADCAST_SUCCESS;
16016    }
16017
16018    final Intent verifyBroadcastLocked(Intent intent) {
16019        // Refuse possible leaked file descriptors
16020        if (intent != null && intent.hasFileDescriptors() == true) {
16021            throw new IllegalArgumentException("File descriptors passed in Intent");
16022        }
16023
16024        int flags = intent.getFlags();
16025
16026        if (!mProcessesReady) {
16027            // if the caller really truly claims to know what they're doing, go
16028            // ahead and allow the broadcast without launching any receivers
16029            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16030                intent = new Intent(intent);
16031                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16032            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16033                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16034                        + " before boot completion");
16035                throw new IllegalStateException("Cannot broadcast before boot completed");
16036            }
16037        }
16038
16039        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16040            throw new IllegalArgumentException(
16041                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16042        }
16043
16044        return intent;
16045    }
16046
16047    public final int broadcastIntent(IApplicationThread caller,
16048            Intent intent, String resolvedType, IIntentReceiver resultTo,
16049            int resultCode, String resultData, Bundle map,
16050            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16051        enforceNotIsolatedCaller("broadcastIntent");
16052        synchronized(this) {
16053            intent = verifyBroadcastLocked(intent);
16054
16055            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16056            final int callingPid = Binder.getCallingPid();
16057            final int callingUid = Binder.getCallingUid();
16058            final long origId = Binder.clearCallingIdentity();
16059            int res = broadcastIntentLocked(callerApp,
16060                    callerApp != null ? callerApp.info.packageName : null,
16061                    intent, resolvedType, resultTo,
16062                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16063                    callingPid, callingUid, userId);
16064            Binder.restoreCallingIdentity(origId);
16065            return res;
16066        }
16067    }
16068
16069    int broadcastIntentInPackage(String packageName, int uid,
16070            Intent intent, String resolvedType, IIntentReceiver resultTo,
16071            int resultCode, String resultData, Bundle map,
16072            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16073        synchronized(this) {
16074            intent = verifyBroadcastLocked(intent);
16075
16076            final long origId = Binder.clearCallingIdentity();
16077            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16078                    resultTo, resultCode, resultData, map, requiredPermission,
16079                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16080            Binder.restoreCallingIdentity(origId);
16081            return res;
16082        }
16083    }
16084
16085    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16086        // Refuse possible leaked file descriptors
16087        if (intent != null && intent.hasFileDescriptors() == true) {
16088            throw new IllegalArgumentException("File descriptors passed in Intent");
16089        }
16090
16091        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16092                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16093
16094        synchronized(this) {
16095            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16096                    != PackageManager.PERMISSION_GRANTED) {
16097                String msg = "Permission Denial: unbroadcastIntent() from pid="
16098                        + Binder.getCallingPid()
16099                        + ", uid=" + Binder.getCallingUid()
16100                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16101                Slog.w(TAG, msg);
16102                throw new SecurityException(msg);
16103            }
16104            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16105            if (stickies != null) {
16106                ArrayList<Intent> list = stickies.get(intent.getAction());
16107                if (list != null) {
16108                    int N = list.size();
16109                    int i;
16110                    for (i=0; i<N; i++) {
16111                        if (intent.filterEquals(list.get(i))) {
16112                            list.remove(i);
16113                            break;
16114                        }
16115                    }
16116                    if (list.size() <= 0) {
16117                        stickies.remove(intent.getAction());
16118                    }
16119                }
16120                if (stickies.size() <= 0) {
16121                    mStickyBroadcasts.remove(userId);
16122                }
16123            }
16124        }
16125    }
16126
16127    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16128            String resultData, Bundle resultExtras, boolean resultAbort) {
16129        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16130        if (r == null) {
16131            Slog.w(TAG, "finishReceiver called but not found on queue");
16132            return false;
16133        }
16134
16135        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16136    }
16137
16138    void backgroundServicesFinishedLocked(int userId) {
16139        for (BroadcastQueue queue : mBroadcastQueues) {
16140            queue.backgroundServicesFinishedLocked(userId);
16141        }
16142    }
16143
16144    public void finishReceiver(IBinder who, int resultCode, String resultData,
16145            Bundle resultExtras, boolean resultAbort) {
16146        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16147
16148        // Refuse possible leaked file descriptors
16149        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16150            throw new IllegalArgumentException("File descriptors passed in Bundle");
16151        }
16152
16153        final long origId = Binder.clearCallingIdentity();
16154        try {
16155            boolean doNext = false;
16156            BroadcastRecord r;
16157
16158            synchronized(this) {
16159                r = broadcastRecordForReceiverLocked(who);
16160                if (r != null) {
16161                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16162                        resultData, resultExtras, resultAbort, true);
16163                }
16164            }
16165
16166            if (doNext) {
16167                r.queue.processNextBroadcast(false);
16168            }
16169            trimApplications();
16170        } finally {
16171            Binder.restoreCallingIdentity(origId);
16172        }
16173    }
16174
16175    // =========================================================
16176    // INSTRUMENTATION
16177    // =========================================================
16178
16179    public boolean startInstrumentation(ComponentName className,
16180            String profileFile, int flags, Bundle arguments,
16181            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16182            int userId, String abiOverride) {
16183        enforceNotIsolatedCaller("startInstrumentation");
16184        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16185                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16186        // Refuse possible leaked file descriptors
16187        if (arguments != null && arguments.hasFileDescriptors()) {
16188            throw new IllegalArgumentException("File descriptors passed in Bundle");
16189        }
16190
16191        synchronized(this) {
16192            InstrumentationInfo ii = null;
16193            ApplicationInfo ai = null;
16194            try {
16195                ii = mContext.getPackageManager().getInstrumentationInfo(
16196                    className, STOCK_PM_FLAGS);
16197                ai = AppGlobals.getPackageManager().getApplicationInfo(
16198                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16199            } catch (PackageManager.NameNotFoundException e) {
16200            } catch (RemoteException e) {
16201            }
16202            if (ii == null) {
16203                reportStartInstrumentationFailure(watcher, className,
16204                        "Unable to find instrumentation info for: " + className);
16205                return false;
16206            }
16207            if (ai == null) {
16208                reportStartInstrumentationFailure(watcher, className,
16209                        "Unable to find instrumentation target package: " + ii.targetPackage);
16210                return false;
16211            }
16212
16213            int match = mContext.getPackageManager().checkSignatures(
16214                    ii.targetPackage, ii.packageName);
16215            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16216                String msg = "Permission Denial: starting instrumentation "
16217                        + className + " from pid="
16218                        + Binder.getCallingPid()
16219                        + ", uid=" + Binder.getCallingPid()
16220                        + " not allowed because package " + ii.packageName
16221                        + " does not have a signature matching the target "
16222                        + ii.targetPackage;
16223                reportStartInstrumentationFailure(watcher, className, msg);
16224                throw new SecurityException(msg);
16225            }
16226
16227            final long origId = Binder.clearCallingIdentity();
16228            // Instrumentation can kill and relaunch even persistent processes
16229            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16230                    "start instr");
16231            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16232            app.instrumentationClass = className;
16233            app.instrumentationInfo = ai;
16234            app.instrumentationProfileFile = profileFile;
16235            app.instrumentationArguments = arguments;
16236            app.instrumentationWatcher = watcher;
16237            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16238            app.instrumentationResultClass = className;
16239            Binder.restoreCallingIdentity(origId);
16240        }
16241
16242        return true;
16243    }
16244
16245    /**
16246     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16247     * error to the logs, but if somebody is watching, send the report there too.  This enables
16248     * the "am" command to report errors with more information.
16249     *
16250     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16251     * @param cn The component name of the instrumentation.
16252     * @param report The error report.
16253     */
16254    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16255            ComponentName cn, String report) {
16256        Slog.w(TAG, report);
16257        try {
16258            if (watcher != null) {
16259                Bundle results = new Bundle();
16260                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16261                results.putString("Error", report);
16262                watcher.instrumentationStatus(cn, -1, results);
16263            }
16264        } catch (RemoteException e) {
16265            Slog.w(TAG, e);
16266        }
16267    }
16268
16269    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16270        if (app.instrumentationWatcher != null) {
16271            try {
16272                // NOTE:  IInstrumentationWatcher *must* be oneway here
16273                app.instrumentationWatcher.instrumentationFinished(
16274                    app.instrumentationClass,
16275                    resultCode,
16276                    results);
16277            } catch (RemoteException e) {
16278            }
16279        }
16280        if (app.instrumentationUiAutomationConnection != null) {
16281            try {
16282                app.instrumentationUiAutomationConnection.shutdown();
16283            } catch (RemoteException re) {
16284                /* ignore */
16285            }
16286            // Only a UiAutomation can set this flag and now that
16287            // it is finished we make sure it is reset to its default.
16288            mUserIsMonkey = false;
16289        }
16290        app.instrumentationWatcher = null;
16291        app.instrumentationUiAutomationConnection = null;
16292        app.instrumentationClass = null;
16293        app.instrumentationInfo = null;
16294        app.instrumentationProfileFile = null;
16295        app.instrumentationArguments = null;
16296
16297        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16298                "finished inst");
16299    }
16300
16301    public void finishInstrumentation(IApplicationThread target,
16302            int resultCode, Bundle results) {
16303        int userId = UserHandle.getCallingUserId();
16304        // Refuse possible leaked file descriptors
16305        if (results != null && results.hasFileDescriptors()) {
16306            throw new IllegalArgumentException("File descriptors passed in Intent");
16307        }
16308
16309        synchronized(this) {
16310            ProcessRecord app = getRecordForAppLocked(target);
16311            if (app == null) {
16312                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16313                return;
16314            }
16315            final long origId = Binder.clearCallingIdentity();
16316            finishInstrumentationLocked(app, resultCode, results);
16317            Binder.restoreCallingIdentity(origId);
16318        }
16319    }
16320
16321    // =========================================================
16322    // CONFIGURATION
16323    // =========================================================
16324
16325    public ConfigurationInfo getDeviceConfigurationInfo() {
16326        ConfigurationInfo config = new ConfigurationInfo();
16327        synchronized (this) {
16328            config.reqTouchScreen = mConfiguration.touchscreen;
16329            config.reqKeyboardType = mConfiguration.keyboard;
16330            config.reqNavigation = mConfiguration.navigation;
16331            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16332                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16333                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16334            }
16335            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16336                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16337                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16338            }
16339            config.reqGlEsVersion = GL_ES_VERSION;
16340        }
16341        return config;
16342    }
16343
16344    ActivityStack getFocusedStack() {
16345        return mStackSupervisor.getFocusedStack();
16346    }
16347
16348    public Configuration getConfiguration() {
16349        Configuration ci;
16350        synchronized(this) {
16351            ci = new Configuration(mConfiguration);
16352        }
16353        return ci;
16354    }
16355
16356    public void updatePersistentConfiguration(Configuration values) {
16357        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16358                "updateConfiguration()");
16359        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16360                "updateConfiguration()");
16361        if (values == null) {
16362            throw new NullPointerException("Configuration must not be null");
16363        }
16364
16365        synchronized(this) {
16366            final long origId = Binder.clearCallingIdentity();
16367            updateConfigurationLocked(values, null, true, false);
16368            Binder.restoreCallingIdentity(origId);
16369        }
16370    }
16371
16372    public void updateConfiguration(Configuration values) {
16373        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16374                "updateConfiguration()");
16375
16376        synchronized(this) {
16377            if (values == null && mWindowManager != null) {
16378                // sentinel: fetch the current configuration from the window manager
16379                values = mWindowManager.computeNewConfiguration();
16380            }
16381
16382            if (mWindowManager != null) {
16383                mProcessList.applyDisplaySize(mWindowManager);
16384            }
16385
16386            final long origId = Binder.clearCallingIdentity();
16387            if (values != null) {
16388                Settings.System.clearConfiguration(values);
16389            }
16390            updateConfigurationLocked(values, null, false, false);
16391            Binder.restoreCallingIdentity(origId);
16392        }
16393    }
16394
16395    /**
16396     * Do either or both things: (1) change the current configuration, and (2)
16397     * make sure the given activity is running with the (now) current
16398     * configuration.  Returns true if the activity has been left running, or
16399     * false if <var>starting</var> is being destroyed to match the new
16400     * configuration.
16401     * @param persistent TODO
16402     */
16403    boolean updateConfigurationLocked(Configuration values,
16404            ActivityRecord starting, boolean persistent, boolean initLocale) {
16405        int changes = 0;
16406
16407        if (values != null) {
16408            Configuration newConfig = new Configuration(mConfiguration);
16409            changes = newConfig.updateFrom(values);
16410            if (changes != 0) {
16411                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16412                    Slog.i(TAG, "Updating configuration to: " + values);
16413                }
16414
16415                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16416
16417                if (values.locale != null && !initLocale) {
16418                    saveLocaleLocked(values.locale,
16419                                     !values.locale.equals(mConfiguration.locale),
16420                                     values.userSetLocale);
16421                }
16422
16423                mConfigurationSeq++;
16424                if (mConfigurationSeq <= 0) {
16425                    mConfigurationSeq = 1;
16426                }
16427                newConfig.seq = mConfigurationSeq;
16428                mConfiguration = newConfig;
16429                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16430                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16431                //mUsageStatsService.noteStartConfig(newConfig);
16432
16433                final Configuration configCopy = new Configuration(mConfiguration);
16434
16435                // TODO: If our config changes, should we auto dismiss any currently
16436                // showing dialogs?
16437                mShowDialogs = shouldShowDialogs(newConfig);
16438
16439                AttributeCache ac = AttributeCache.instance();
16440                if (ac != null) {
16441                    ac.updateConfiguration(configCopy);
16442                }
16443
16444                // Make sure all resources in our process are updated
16445                // right now, so that anyone who is going to retrieve
16446                // resource values after we return will be sure to get
16447                // the new ones.  This is especially important during
16448                // boot, where the first config change needs to guarantee
16449                // all resources have that config before following boot
16450                // code is executed.
16451                mSystemThread.applyConfigurationToResources(configCopy);
16452
16453                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16454                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16455                    msg.obj = new Configuration(configCopy);
16456                    mHandler.sendMessage(msg);
16457                }
16458
16459                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16460                    ProcessRecord app = mLruProcesses.get(i);
16461                    try {
16462                        if (app.thread != null) {
16463                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16464                                    + app.processName + " new config " + mConfiguration);
16465                            app.thread.scheduleConfigurationChanged(configCopy);
16466                        }
16467                    } catch (Exception e) {
16468                    }
16469                }
16470                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16471                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16472                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16473                        | Intent.FLAG_RECEIVER_FOREGROUND);
16474                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16475                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16476                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16477                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16478                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16479                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16480                    broadcastIntentLocked(null, null, intent,
16481                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16482                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16483                }
16484            }
16485        }
16486
16487        boolean kept = true;
16488        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16489        // mainStack is null during startup.
16490        if (mainStack != null) {
16491            if (changes != 0 && starting == null) {
16492                // If the configuration changed, and the caller is not already
16493                // in the process of starting an activity, then find the top
16494                // activity to check if its configuration needs to change.
16495                starting = mainStack.topRunningActivityLocked(null);
16496            }
16497
16498            if (starting != null) {
16499                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16500                // And we need to make sure at this point that all other activities
16501                // are made visible with the correct configuration.
16502                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16503            }
16504        }
16505
16506        if (values != null && mWindowManager != null) {
16507            mWindowManager.setNewConfiguration(mConfiguration);
16508        }
16509
16510        return kept;
16511    }
16512
16513    /**
16514     * Decide based on the configuration whether we should shouw the ANR,
16515     * crash, etc dialogs.  The idea is that if there is no affordnace to
16516     * press the on-screen buttons, we shouldn't show the dialog.
16517     *
16518     * A thought: SystemUI might also want to get told about this, the Power
16519     * dialog / global actions also might want different behaviors.
16520     */
16521    private static final boolean shouldShowDialogs(Configuration config) {
16522        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16523                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16524    }
16525
16526    /**
16527     * Save the locale.  You must be inside a synchronized (this) block.
16528     */
16529    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16530        if(isDiff) {
16531            SystemProperties.set("user.language", l.getLanguage());
16532            SystemProperties.set("user.region", l.getCountry());
16533        }
16534
16535        if(isPersist) {
16536            SystemProperties.set("persist.sys.language", l.getLanguage());
16537            SystemProperties.set("persist.sys.country", l.getCountry());
16538            SystemProperties.set("persist.sys.localevar", l.getVariant());
16539
16540            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16541        }
16542    }
16543
16544    @Override
16545    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16546        synchronized (this) {
16547            ActivityRecord srec = ActivityRecord.forToken(token);
16548            if (srec.task != null && srec.task.stack != null) {
16549                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16550            }
16551        }
16552        return false;
16553    }
16554
16555    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16556            Intent resultData) {
16557
16558        synchronized (this) {
16559            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16560            if (stack != null) {
16561                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16562            }
16563            return false;
16564        }
16565    }
16566
16567    public int getLaunchedFromUid(IBinder activityToken) {
16568        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16569        if (srec == null) {
16570            return -1;
16571        }
16572        return srec.launchedFromUid;
16573    }
16574
16575    public String getLaunchedFromPackage(IBinder activityToken) {
16576        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16577        if (srec == null) {
16578            return null;
16579        }
16580        return srec.launchedFromPackage;
16581    }
16582
16583    // =========================================================
16584    // LIFETIME MANAGEMENT
16585    // =========================================================
16586
16587    // Returns which broadcast queue the app is the current [or imminent] receiver
16588    // on, or 'null' if the app is not an active broadcast recipient.
16589    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16590        BroadcastRecord r = app.curReceiver;
16591        if (r != null) {
16592            return r.queue;
16593        }
16594
16595        // It's not the current receiver, but it might be starting up to become one
16596        synchronized (this) {
16597            for (BroadcastQueue queue : mBroadcastQueues) {
16598                r = queue.mPendingBroadcast;
16599                if (r != null && r.curApp == app) {
16600                    // found it; report which queue it's in
16601                    return queue;
16602                }
16603            }
16604        }
16605
16606        return null;
16607    }
16608
16609    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16610            boolean doingAll, long now) {
16611        if (mAdjSeq == app.adjSeq) {
16612            // This adjustment has already been computed.
16613            return app.curRawAdj;
16614        }
16615
16616        if (app.thread == null) {
16617            app.adjSeq = mAdjSeq;
16618            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16619            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16620            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16621        }
16622
16623        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16624        app.adjSource = null;
16625        app.adjTarget = null;
16626        app.empty = false;
16627        app.cached = false;
16628
16629        final int activitiesSize = app.activities.size();
16630
16631        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16632            // The max adjustment doesn't allow this app to be anything
16633            // below foreground, so it is not worth doing work for it.
16634            app.adjType = "fixed";
16635            app.adjSeq = mAdjSeq;
16636            app.curRawAdj = app.maxAdj;
16637            app.foregroundActivities = false;
16638            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16639            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16640            // System processes can do UI, and when they do we want to have
16641            // them trim their memory after the user leaves the UI.  To
16642            // facilitate this, here we need to determine whether or not it
16643            // is currently showing UI.
16644            app.systemNoUi = true;
16645            if (app == TOP_APP) {
16646                app.systemNoUi = false;
16647            } else if (activitiesSize > 0) {
16648                for (int j = 0; j < activitiesSize; j++) {
16649                    final ActivityRecord r = app.activities.get(j);
16650                    if (r.visible) {
16651                        app.systemNoUi = false;
16652                    }
16653                }
16654            }
16655            if (!app.systemNoUi) {
16656                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16657            }
16658            return (app.curAdj=app.maxAdj);
16659        }
16660
16661        app.systemNoUi = false;
16662
16663        // Determine the importance of the process, starting with most
16664        // important to least, and assign an appropriate OOM adjustment.
16665        int adj;
16666        int schedGroup;
16667        int procState;
16668        boolean foregroundActivities = false;
16669        BroadcastQueue queue;
16670        if (app == TOP_APP) {
16671            // The last app on the list is the foreground app.
16672            adj = ProcessList.FOREGROUND_APP_ADJ;
16673            schedGroup = Process.THREAD_GROUP_DEFAULT;
16674            app.adjType = "top-activity";
16675            foregroundActivities = true;
16676            procState = ActivityManager.PROCESS_STATE_TOP;
16677        } else if (app.instrumentationClass != null) {
16678            // Don't want to kill running instrumentation.
16679            adj = ProcessList.FOREGROUND_APP_ADJ;
16680            schedGroup = Process.THREAD_GROUP_DEFAULT;
16681            app.adjType = "instrumentation";
16682            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16683        } else if ((queue = isReceivingBroadcast(app)) != null) {
16684            // An app that is currently receiving a broadcast also
16685            // counts as being in the foreground for OOM killer purposes.
16686            // It's placed in a sched group based on the nature of the
16687            // broadcast as reflected by which queue it's active in.
16688            adj = ProcessList.FOREGROUND_APP_ADJ;
16689            schedGroup = (queue == mFgBroadcastQueue)
16690                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16691            app.adjType = "broadcast";
16692            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16693        } else if (app.executingServices.size() > 0) {
16694            // An app that is currently executing a service callback also
16695            // counts as being in the foreground.
16696            adj = ProcessList.FOREGROUND_APP_ADJ;
16697            schedGroup = app.execServicesFg ?
16698                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16699            app.adjType = "exec-service";
16700            procState = ActivityManager.PROCESS_STATE_SERVICE;
16701            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16702        } else {
16703            // As far as we know the process is empty.  We may change our mind later.
16704            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16705            // At this point we don't actually know the adjustment.  Use the cached adj
16706            // value that the caller wants us to.
16707            adj = cachedAdj;
16708            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16709            app.cached = true;
16710            app.empty = true;
16711            app.adjType = "cch-empty";
16712        }
16713
16714        // Examine all activities if not already foreground.
16715        if (!foregroundActivities && activitiesSize > 0) {
16716            for (int j = 0; j < activitiesSize; j++) {
16717                final ActivityRecord r = app.activities.get(j);
16718                if (r.app != app) {
16719                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16720                            + app + "?!?");
16721                    continue;
16722                }
16723                if (r.visible) {
16724                    // App has a visible activity; only upgrade adjustment.
16725                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16726                        adj = ProcessList.VISIBLE_APP_ADJ;
16727                        app.adjType = "visible";
16728                    }
16729                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16730                        procState = ActivityManager.PROCESS_STATE_TOP;
16731                    }
16732                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16733                    app.cached = false;
16734                    app.empty = false;
16735                    foregroundActivities = true;
16736                    break;
16737                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16738                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16739                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16740                        app.adjType = "pausing";
16741                    }
16742                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16743                        procState = ActivityManager.PROCESS_STATE_TOP;
16744                    }
16745                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16746                    app.cached = false;
16747                    app.empty = false;
16748                    foregroundActivities = true;
16749                } else if (r.state == ActivityState.STOPPING) {
16750                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16751                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16752                        app.adjType = "stopping";
16753                    }
16754                    // For the process state, we will at this point consider the
16755                    // process to be cached.  It will be cached either as an activity
16756                    // or empty depending on whether the activity is finishing.  We do
16757                    // this so that we can treat the process as cached for purposes of
16758                    // memory trimming (determing current memory level, trim command to
16759                    // send to process) since there can be an arbitrary number of stopping
16760                    // processes and they should soon all go into the cached state.
16761                    if (!r.finishing) {
16762                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16763                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16764                        }
16765                    }
16766                    app.cached = false;
16767                    app.empty = false;
16768                    foregroundActivities = true;
16769                } else {
16770                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16771                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16772                        app.adjType = "cch-act";
16773                    }
16774                }
16775            }
16776        }
16777
16778        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16779            if (app.foregroundServices) {
16780                // The user is aware of this app, so make it visible.
16781                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16782                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16783                app.cached = false;
16784                app.adjType = "fg-service";
16785                schedGroup = Process.THREAD_GROUP_DEFAULT;
16786            } else if (app.forcingToForeground != null) {
16787                // The user is aware of this app, so make it visible.
16788                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16789                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16790                app.cached = false;
16791                app.adjType = "force-fg";
16792                app.adjSource = app.forcingToForeground;
16793                schedGroup = Process.THREAD_GROUP_DEFAULT;
16794            }
16795        }
16796
16797        if (app == mHeavyWeightProcess) {
16798            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16799                // We don't want to kill the current heavy-weight process.
16800                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16801                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16802                app.cached = false;
16803                app.adjType = "heavy";
16804            }
16805            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16806                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16807            }
16808        }
16809
16810        if (app == mHomeProcess) {
16811            if (adj > ProcessList.HOME_APP_ADJ) {
16812                // This process is hosting what we currently consider to be the
16813                // home app, so we don't want to let it go into the background.
16814                adj = ProcessList.HOME_APP_ADJ;
16815                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16816                app.cached = false;
16817                app.adjType = "home";
16818            }
16819            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16820                procState = ActivityManager.PROCESS_STATE_HOME;
16821            }
16822        }
16823
16824        if (app == mPreviousProcess && app.activities.size() > 0) {
16825            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16826                // This was the previous process that showed UI to the user.
16827                // We want to try to keep it around more aggressively, to give
16828                // a good experience around switching between two apps.
16829                adj = ProcessList.PREVIOUS_APP_ADJ;
16830                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16831                app.cached = false;
16832                app.adjType = "previous";
16833            }
16834            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16835                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16836            }
16837        }
16838
16839        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16840                + " reason=" + app.adjType);
16841
16842        // By default, we use the computed adjustment.  It may be changed if
16843        // there are applications dependent on our services or providers, but
16844        // this gives us a baseline and makes sure we don't get into an
16845        // infinite recursion.
16846        app.adjSeq = mAdjSeq;
16847        app.curRawAdj = adj;
16848        app.hasStartedServices = false;
16849
16850        if (mBackupTarget != null && app == mBackupTarget.app) {
16851            // If possible we want to avoid killing apps while they're being backed up
16852            if (adj > ProcessList.BACKUP_APP_ADJ) {
16853                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16854                adj = ProcessList.BACKUP_APP_ADJ;
16855                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16856                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16857                }
16858                app.adjType = "backup";
16859                app.cached = false;
16860            }
16861            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16862                procState = ActivityManager.PROCESS_STATE_BACKUP;
16863            }
16864        }
16865
16866        boolean mayBeTop = false;
16867
16868        for (int is = app.services.size()-1;
16869                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16870                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16871                        || procState > ActivityManager.PROCESS_STATE_TOP);
16872                is--) {
16873            ServiceRecord s = app.services.valueAt(is);
16874            if (s.startRequested) {
16875                app.hasStartedServices = true;
16876                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16877                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16878                }
16879                if (app.hasShownUi && app != mHomeProcess) {
16880                    // If this process has shown some UI, let it immediately
16881                    // go to the LRU list because it may be pretty heavy with
16882                    // UI stuff.  We'll tag it with a label just to help
16883                    // debug and understand what is going on.
16884                    if (adj > ProcessList.SERVICE_ADJ) {
16885                        app.adjType = "cch-started-ui-services";
16886                    }
16887                } else {
16888                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16889                        // This service has seen some activity within
16890                        // recent memory, so we will keep its process ahead
16891                        // of the background processes.
16892                        if (adj > ProcessList.SERVICE_ADJ) {
16893                            adj = ProcessList.SERVICE_ADJ;
16894                            app.adjType = "started-services";
16895                            app.cached = false;
16896                        }
16897                    }
16898                    // If we have let the service slide into the background
16899                    // state, still have some text describing what it is doing
16900                    // even though the service no longer has an impact.
16901                    if (adj > ProcessList.SERVICE_ADJ) {
16902                        app.adjType = "cch-started-services";
16903                    }
16904                }
16905            }
16906            for (int conni = s.connections.size()-1;
16907                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16908                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16909                            || procState > ActivityManager.PROCESS_STATE_TOP);
16910                    conni--) {
16911                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16912                for (int i = 0;
16913                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16914                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16915                                || procState > ActivityManager.PROCESS_STATE_TOP);
16916                        i++) {
16917                    // XXX should compute this based on the max of
16918                    // all connected clients.
16919                    ConnectionRecord cr = clist.get(i);
16920                    if (cr.binding.client == app) {
16921                        // Binding to ourself is not interesting.
16922                        continue;
16923                    }
16924                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16925                        ProcessRecord client = cr.binding.client;
16926                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16927                                TOP_APP, doingAll, now);
16928                        int clientProcState = client.curProcState;
16929                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16930                            // If the other app is cached for any reason, for purposes here
16931                            // we are going to consider it empty.  The specific cached state
16932                            // doesn't propagate except under certain conditions.
16933                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16934                        }
16935                        String adjType = null;
16936                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16937                            // Not doing bind OOM management, so treat
16938                            // this guy more like a started service.
16939                            if (app.hasShownUi && app != mHomeProcess) {
16940                                // If this process has shown some UI, let it immediately
16941                                // go to the LRU list because it may be pretty heavy with
16942                                // UI stuff.  We'll tag it with a label just to help
16943                                // debug and understand what is going on.
16944                                if (adj > clientAdj) {
16945                                    adjType = "cch-bound-ui-services";
16946                                }
16947                                app.cached = false;
16948                                clientAdj = adj;
16949                                clientProcState = procState;
16950                            } else {
16951                                if (now >= (s.lastActivity
16952                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16953                                    // This service has not seen activity within
16954                                    // recent memory, so allow it to drop to the
16955                                    // LRU list if there is no other reason to keep
16956                                    // it around.  We'll also tag it with a label just
16957                                    // to help debug and undertand what is going on.
16958                                    if (adj > clientAdj) {
16959                                        adjType = "cch-bound-services";
16960                                    }
16961                                    clientAdj = adj;
16962                                }
16963                            }
16964                        }
16965                        if (adj > clientAdj) {
16966                            // If this process has recently shown UI, and
16967                            // the process that is binding to it is less
16968                            // important than being visible, then we don't
16969                            // care about the binding as much as we care
16970                            // about letting this process get into the LRU
16971                            // list to be killed and restarted if needed for
16972                            // memory.
16973                            if (app.hasShownUi && app != mHomeProcess
16974                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16975                                adjType = "cch-bound-ui-services";
16976                            } else {
16977                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16978                                        |Context.BIND_IMPORTANT)) != 0) {
16979                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16980                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16981                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16982                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16983                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16984                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16985                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16986                                    adj = clientAdj;
16987                                } else {
16988                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16989                                        adj = ProcessList.VISIBLE_APP_ADJ;
16990                                    }
16991                                }
16992                                if (!client.cached) {
16993                                    app.cached = false;
16994                                }
16995                                adjType = "service";
16996                            }
16997                        }
16998                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16999                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17000                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17001                            }
17002                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17003                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17004                                    // Special handling of clients who are in the top state.
17005                                    // We *may* want to consider this process to be in the
17006                                    // top state as well, but only if there is not another
17007                                    // reason for it to be running.  Being on the top is a
17008                                    // special state, meaning you are specifically running
17009                                    // for the current top app.  If the process is already
17010                                    // running in the background for some other reason, it
17011                                    // is more important to continue considering it to be
17012                                    // in the background state.
17013                                    mayBeTop = true;
17014                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17015                                } else {
17016                                    // Special handling for above-top states (persistent
17017                                    // processes).  These should not bring the current process
17018                                    // into the top state, since they are not on top.  Instead
17019                                    // give them the best state after that.
17020                                    clientProcState =
17021                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17022                                }
17023                            }
17024                        } else {
17025                            if (clientProcState <
17026                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17027                                clientProcState =
17028                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17029                            }
17030                        }
17031                        if (procState > clientProcState) {
17032                            procState = clientProcState;
17033                        }
17034                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17035                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17036                            app.pendingUiClean = true;
17037                        }
17038                        if (adjType != null) {
17039                            app.adjType = adjType;
17040                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17041                                    .REASON_SERVICE_IN_USE;
17042                            app.adjSource = cr.binding.client;
17043                            app.adjSourceProcState = clientProcState;
17044                            app.adjTarget = s.name;
17045                        }
17046                    }
17047                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17048                        app.treatLikeActivity = true;
17049                    }
17050                    final ActivityRecord a = cr.activity;
17051                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17052                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17053                                (a.visible || a.state == ActivityState.RESUMED
17054                                 || a.state == ActivityState.PAUSING)) {
17055                            adj = ProcessList.FOREGROUND_APP_ADJ;
17056                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17057                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17058                            }
17059                            app.cached = false;
17060                            app.adjType = "service";
17061                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17062                                    .REASON_SERVICE_IN_USE;
17063                            app.adjSource = a;
17064                            app.adjSourceProcState = procState;
17065                            app.adjTarget = s.name;
17066                        }
17067                    }
17068                }
17069            }
17070        }
17071
17072        for (int provi = app.pubProviders.size()-1;
17073                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17074                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17075                        || procState > ActivityManager.PROCESS_STATE_TOP);
17076                provi--) {
17077            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17078            for (int i = cpr.connections.size()-1;
17079                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17080                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17081                            || procState > ActivityManager.PROCESS_STATE_TOP);
17082                    i--) {
17083                ContentProviderConnection conn = cpr.connections.get(i);
17084                ProcessRecord client = conn.client;
17085                if (client == app) {
17086                    // Being our own client is not interesting.
17087                    continue;
17088                }
17089                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17090                int clientProcState = client.curProcState;
17091                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17092                    // If the other app is cached for any reason, for purposes here
17093                    // we are going to consider it empty.
17094                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17095                }
17096                if (adj > clientAdj) {
17097                    if (app.hasShownUi && app != mHomeProcess
17098                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17099                        app.adjType = "cch-ui-provider";
17100                    } else {
17101                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17102                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17103                        app.adjType = "provider";
17104                    }
17105                    app.cached &= client.cached;
17106                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17107                            .REASON_PROVIDER_IN_USE;
17108                    app.adjSource = client;
17109                    app.adjSourceProcState = clientProcState;
17110                    app.adjTarget = cpr.name;
17111                }
17112                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17113                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17114                        // Special handling of clients who are in the top state.
17115                        // We *may* want to consider this process to be in the
17116                        // top state as well, but only if there is not another
17117                        // reason for it to be running.  Being on the top is a
17118                        // special state, meaning you are specifically running
17119                        // for the current top app.  If the process is already
17120                        // running in the background for some other reason, it
17121                        // is more important to continue considering it to be
17122                        // in the background state.
17123                        mayBeTop = true;
17124                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17125                    } else {
17126                        // Special handling for above-top states (persistent
17127                        // processes).  These should not bring the current process
17128                        // into the top state, since they are not on top.  Instead
17129                        // give them the best state after that.
17130                        clientProcState =
17131                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17132                    }
17133                }
17134                if (procState > clientProcState) {
17135                    procState = clientProcState;
17136                }
17137                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17138                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17139                }
17140            }
17141            // If the provider has external (non-framework) process
17142            // dependencies, ensure that its adjustment is at least
17143            // FOREGROUND_APP_ADJ.
17144            if (cpr.hasExternalProcessHandles()) {
17145                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17146                    adj = ProcessList.FOREGROUND_APP_ADJ;
17147                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17148                    app.cached = false;
17149                    app.adjType = "provider";
17150                    app.adjTarget = cpr.name;
17151                }
17152                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17153                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17154                }
17155            }
17156        }
17157
17158        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17159            // A client of one of our services or providers is in the top state.  We
17160            // *may* want to be in the top state, but not if we are already running in
17161            // the background for some other reason.  For the decision here, we are going
17162            // to pick out a few specific states that we want to remain in when a client
17163            // is top (states that tend to be longer-term) and otherwise allow it to go
17164            // to the top state.
17165            switch (procState) {
17166                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17167                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17168                case ActivityManager.PROCESS_STATE_SERVICE:
17169                    // These all are longer-term states, so pull them up to the top
17170                    // of the background states, but not all the way to the top state.
17171                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17172                    break;
17173                default:
17174                    // Otherwise, top is a better choice, so take it.
17175                    procState = ActivityManager.PROCESS_STATE_TOP;
17176                    break;
17177            }
17178        }
17179
17180        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17181            if (app.hasClientActivities) {
17182                // This is a cached process, but with client activities.  Mark it so.
17183                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17184                app.adjType = "cch-client-act";
17185            } else if (app.treatLikeActivity) {
17186                // This is a cached process, but somebody wants us to treat it like it has
17187                // an activity, okay!
17188                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17189                app.adjType = "cch-as-act";
17190            }
17191        }
17192
17193        if (adj == ProcessList.SERVICE_ADJ) {
17194            if (doingAll) {
17195                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17196                mNewNumServiceProcs++;
17197                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17198                if (!app.serviceb) {
17199                    // This service isn't far enough down on the LRU list to
17200                    // normally be a B service, but if we are low on RAM and it
17201                    // is large we want to force it down since we would prefer to
17202                    // keep launcher over it.
17203                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17204                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17205                        app.serviceHighRam = true;
17206                        app.serviceb = true;
17207                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17208                    } else {
17209                        mNewNumAServiceProcs++;
17210                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17211                    }
17212                } else {
17213                    app.serviceHighRam = false;
17214                }
17215            }
17216            if (app.serviceb) {
17217                adj = ProcessList.SERVICE_B_ADJ;
17218            }
17219        }
17220
17221        app.curRawAdj = adj;
17222
17223        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17224        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17225        if (adj > app.maxAdj) {
17226            adj = app.maxAdj;
17227            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17228                schedGroup = Process.THREAD_GROUP_DEFAULT;
17229            }
17230        }
17231
17232        // Do final modification to adj.  Everything we do between here and applying
17233        // the final setAdj must be done in this function, because we will also use
17234        // it when computing the final cached adj later.  Note that we don't need to
17235        // worry about this for max adj above, since max adj will always be used to
17236        // keep it out of the cached vaues.
17237        app.curAdj = app.modifyRawOomAdj(adj);
17238        app.curSchedGroup = schedGroup;
17239        app.curProcState = procState;
17240        app.foregroundActivities = foregroundActivities;
17241
17242        return app.curRawAdj;
17243    }
17244
17245    /**
17246     * Schedule PSS collection of a process.
17247     */
17248    void requestPssLocked(ProcessRecord proc, int procState) {
17249        if (mPendingPssProcesses.contains(proc)) {
17250            return;
17251        }
17252        if (mPendingPssProcesses.size() == 0) {
17253            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17254        }
17255        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17256        proc.pssProcState = procState;
17257        mPendingPssProcesses.add(proc);
17258    }
17259
17260    /**
17261     * Schedule PSS collection of all processes.
17262     */
17263    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17264        if (!always) {
17265            if (now < (mLastFullPssTime +
17266                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17267                return;
17268            }
17269        }
17270        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17271        mLastFullPssTime = now;
17272        mFullPssPending = true;
17273        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17274        mPendingPssProcesses.clear();
17275        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17276            ProcessRecord app = mLruProcesses.get(i);
17277            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17278                app.pssProcState = app.setProcState;
17279                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17280                        isSleeping(), now);
17281                mPendingPssProcesses.add(app);
17282            }
17283        }
17284        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17285    }
17286
17287    /**
17288     * Ask a given process to GC right now.
17289     */
17290    final void performAppGcLocked(ProcessRecord app) {
17291        try {
17292            app.lastRequestedGc = SystemClock.uptimeMillis();
17293            if (app.thread != null) {
17294                if (app.reportLowMemory) {
17295                    app.reportLowMemory = false;
17296                    app.thread.scheduleLowMemory();
17297                } else {
17298                    app.thread.processInBackground();
17299                }
17300            }
17301        } catch (Exception e) {
17302            // whatever.
17303        }
17304    }
17305
17306    /**
17307     * Returns true if things are idle enough to perform GCs.
17308     */
17309    private final boolean canGcNowLocked() {
17310        boolean processingBroadcasts = false;
17311        for (BroadcastQueue q : mBroadcastQueues) {
17312            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17313                processingBroadcasts = true;
17314            }
17315        }
17316        return !processingBroadcasts
17317                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17318    }
17319
17320    /**
17321     * Perform GCs on all processes that are waiting for it, but only
17322     * if things are idle.
17323     */
17324    final void performAppGcsLocked() {
17325        final int N = mProcessesToGc.size();
17326        if (N <= 0) {
17327            return;
17328        }
17329        if (canGcNowLocked()) {
17330            while (mProcessesToGc.size() > 0) {
17331                ProcessRecord proc = mProcessesToGc.remove(0);
17332                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17333                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17334                            <= SystemClock.uptimeMillis()) {
17335                        // To avoid spamming the system, we will GC processes one
17336                        // at a time, waiting a few seconds between each.
17337                        performAppGcLocked(proc);
17338                        scheduleAppGcsLocked();
17339                        return;
17340                    } else {
17341                        // It hasn't been long enough since we last GCed this
17342                        // process...  put it in the list to wait for its time.
17343                        addProcessToGcListLocked(proc);
17344                        break;
17345                    }
17346                }
17347            }
17348
17349            scheduleAppGcsLocked();
17350        }
17351    }
17352
17353    /**
17354     * If all looks good, perform GCs on all processes waiting for them.
17355     */
17356    final void performAppGcsIfAppropriateLocked() {
17357        if (canGcNowLocked()) {
17358            performAppGcsLocked();
17359            return;
17360        }
17361        // Still not idle, wait some more.
17362        scheduleAppGcsLocked();
17363    }
17364
17365    /**
17366     * Schedule the execution of all pending app GCs.
17367     */
17368    final void scheduleAppGcsLocked() {
17369        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17370
17371        if (mProcessesToGc.size() > 0) {
17372            // Schedule a GC for the time to the next process.
17373            ProcessRecord proc = mProcessesToGc.get(0);
17374            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17375
17376            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17377            long now = SystemClock.uptimeMillis();
17378            if (when < (now+GC_TIMEOUT)) {
17379                when = now + GC_TIMEOUT;
17380            }
17381            mHandler.sendMessageAtTime(msg, when);
17382        }
17383    }
17384
17385    /**
17386     * Add a process to the array of processes waiting to be GCed.  Keeps the
17387     * list in sorted order by the last GC time.  The process can't already be
17388     * on the list.
17389     */
17390    final void addProcessToGcListLocked(ProcessRecord proc) {
17391        boolean added = false;
17392        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17393            if (mProcessesToGc.get(i).lastRequestedGc <
17394                    proc.lastRequestedGc) {
17395                added = true;
17396                mProcessesToGc.add(i+1, proc);
17397                break;
17398            }
17399        }
17400        if (!added) {
17401            mProcessesToGc.add(0, proc);
17402        }
17403    }
17404
17405    /**
17406     * Set up to ask a process to GC itself.  This will either do it
17407     * immediately, or put it on the list of processes to gc the next
17408     * time things are idle.
17409     */
17410    final void scheduleAppGcLocked(ProcessRecord app) {
17411        long now = SystemClock.uptimeMillis();
17412        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17413            return;
17414        }
17415        if (!mProcessesToGc.contains(app)) {
17416            addProcessToGcListLocked(app);
17417            scheduleAppGcsLocked();
17418        }
17419    }
17420
17421    final void checkExcessivePowerUsageLocked(boolean doKills) {
17422        updateCpuStatsNow();
17423
17424        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17425        boolean doWakeKills = doKills;
17426        boolean doCpuKills = doKills;
17427        if (mLastPowerCheckRealtime == 0) {
17428            doWakeKills = false;
17429        }
17430        if (mLastPowerCheckUptime == 0) {
17431            doCpuKills = false;
17432        }
17433        if (stats.isScreenOn()) {
17434            doWakeKills = false;
17435        }
17436        final long curRealtime = SystemClock.elapsedRealtime();
17437        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17438        final long curUptime = SystemClock.uptimeMillis();
17439        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17440        mLastPowerCheckRealtime = curRealtime;
17441        mLastPowerCheckUptime = curUptime;
17442        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17443            doWakeKills = false;
17444        }
17445        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17446            doCpuKills = false;
17447        }
17448        int i = mLruProcesses.size();
17449        while (i > 0) {
17450            i--;
17451            ProcessRecord app = mLruProcesses.get(i);
17452            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17453                long wtime;
17454                synchronized (stats) {
17455                    wtime = stats.getProcessWakeTime(app.info.uid,
17456                            app.pid, curRealtime);
17457                }
17458                long wtimeUsed = wtime - app.lastWakeTime;
17459                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17460                if (DEBUG_POWER) {
17461                    StringBuilder sb = new StringBuilder(128);
17462                    sb.append("Wake for ");
17463                    app.toShortString(sb);
17464                    sb.append(": over ");
17465                    TimeUtils.formatDuration(realtimeSince, sb);
17466                    sb.append(" used ");
17467                    TimeUtils.formatDuration(wtimeUsed, sb);
17468                    sb.append(" (");
17469                    sb.append((wtimeUsed*100)/realtimeSince);
17470                    sb.append("%)");
17471                    Slog.i(TAG, sb.toString());
17472                    sb.setLength(0);
17473                    sb.append("CPU for ");
17474                    app.toShortString(sb);
17475                    sb.append(": over ");
17476                    TimeUtils.formatDuration(uptimeSince, sb);
17477                    sb.append(" used ");
17478                    TimeUtils.formatDuration(cputimeUsed, sb);
17479                    sb.append(" (");
17480                    sb.append((cputimeUsed*100)/uptimeSince);
17481                    sb.append("%)");
17482                    Slog.i(TAG, sb.toString());
17483                }
17484                // If a process has held a wake lock for more
17485                // than 50% of the time during this period,
17486                // that sounds bad.  Kill!
17487                if (doWakeKills && realtimeSince > 0
17488                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17489                    synchronized (stats) {
17490                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17491                                realtimeSince, wtimeUsed);
17492                    }
17493                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17494                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17495                } else if (doCpuKills && uptimeSince > 0
17496                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17497                    synchronized (stats) {
17498                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17499                                uptimeSince, cputimeUsed);
17500                    }
17501                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17502                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17503                } else {
17504                    app.lastWakeTime = wtime;
17505                    app.lastCpuTime = app.curCpuTime;
17506                }
17507            }
17508        }
17509    }
17510
17511    private final boolean applyOomAdjLocked(ProcessRecord app,
17512            ProcessRecord TOP_APP, boolean doingAll, long now) {
17513        boolean success = true;
17514
17515        if (app.curRawAdj != app.setRawAdj) {
17516            app.setRawAdj = app.curRawAdj;
17517        }
17518
17519        int changes = 0;
17520
17521        if (app.curAdj != app.setAdj) {
17522            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17523            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17524                TAG, "Set " + app.pid + " " + app.processName +
17525                " adj " + app.curAdj + ": " + app.adjType);
17526            app.setAdj = app.curAdj;
17527        }
17528
17529        if (app.setSchedGroup != app.curSchedGroup) {
17530            app.setSchedGroup = app.curSchedGroup;
17531            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17532                    "Setting process group of " + app.processName
17533                    + " to " + app.curSchedGroup);
17534            if (app.waitingToKill != null &&
17535                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17536                app.kill(app.waitingToKill, true);
17537                success = false;
17538            } else {
17539                if (true) {
17540                    long oldId = Binder.clearCallingIdentity();
17541                    try {
17542                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17543                    } catch (Exception e) {
17544                        Slog.w(TAG, "Failed setting process group of " + app.pid
17545                                + " to " + app.curSchedGroup);
17546                        e.printStackTrace();
17547                    } finally {
17548                        Binder.restoreCallingIdentity(oldId);
17549                    }
17550                } else {
17551                    if (app.thread != null) {
17552                        try {
17553                            app.thread.setSchedulingGroup(app.curSchedGroup);
17554                        } catch (RemoteException e) {
17555                        }
17556                    }
17557                }
17558                Process.setSwappiness(app.pid,
17559                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17560            }
17561        }
17562        if (app.repForegroundActivities != app.foregroundActivities) {
17563            app.repForegroundActivities = app.foregroundActivities;
17564            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17565        }
17566        if (app.repProcState != app.curProcState) {
17567            app.repProcState = app.curProcState;
17568            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17569            if (app.thread != null) {
17570                try {
17571                    if (false) {
17572                        //RuntimeException h = new RuntimeException("here");
17573                        Slog.i(TAG, "Sending new process state " + app.repProcState
17574                                + " to " + app /*, h*/);
17575                    }
17576                    app.thread.setProcessState(app.repProcState);
17577                } catch (RemoteException e) {
17578                }
17579            }
17580        }
17581        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17582                app.setProcState)) {
17583            app.lastStateTime = now;
17584            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17585                    isSleeping(), now);
17586            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17587                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17588                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17589                    + (app.nextPssTime-now) + ": " + app);
17590        } else {
17591            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17592                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17593                requestPssLocked(app, app.setProcState);
17594                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17595                        isSleeping(), now);
17596            } else if (false && DEBUG_PSS) {
17597                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17598            }
17599        }
17600        if (app.setProcState != app.curProcState) {
17601            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17602                    "Proc state change of " + app.processName
17603                    + " to " + app.curProcState);
17604            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17605            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17606            if (setImportant && !curImportant) {
17607                // This app is no longer something we consider important enough to allow to
17608                // use arbitrary amounts of battery power.  Note
17609                // its current wake lock time to later know to kill it if
17610                // it is not behaving well.
17611                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17612                synchronized (stats) {
17613                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17614                            app.pid, SystemClock.elapsedRealtime());
17615                }
17616                app.lastCpuTime = app.curCpuTime;
17617
17618            }
17619            app.setProcState = app.curProcState;
17620            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17621                app.notCachedSinceIdle = false;
17622            }
17623            if (!doingAll) {
17624                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17625            } else {
17626                app.procStateChanged = true;
17627            }
17628        }
17629
17630        if (changes != 0) {
17631            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17632            int i = mPendingProcessChanges.size()-1;
17633            ProcessChangeItem item = null;
17634            while (i >= 0) {
17635                item = mPendingProcessChanges.get(i);
17636                if (item.pid == app.pid) {
17637                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17638                    break;
17639                }
17640                i--;
17641            }
17642            if (i < 0) {
17643                // No existing item in pending changes; need a new one.
17644                final int NA = mAvailProcessChanges.size();
17645                if (NA > 0) {
17646                    item = mAvailProcessChanges.remove(NA-1);
17647                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17648                } else {
17649                    item = new ProcessChangeItem();
17650                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17651                }
17652                item.changes = 0;
17653                item.pid = app.pid;
17654                item.uid = app.info.uid;
17655                if (mPendingProcessChanges.size() == 0) {
17656                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17657                            "*** Enqueueing dispatch processes changed!");
17658                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17659                }
17660                mPendingProcessChanges.add(item);
17661            }
17662            item.changes |= changes;
17663            item.processState = app.repProcState;
17664            item.foregroundActivities = app.repForegroundActivities;
17665            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17666                    + Integer.toHexString(System.identityHashCode(item))
17667                    + " " + app.toShortString() + ": changes=" + item.changes
17668                    + " procState=" + item.processState
17669                    + " foreground=" + item.foregroundActivities
17670                    + " type=" + app.adjType + " source=" + app.adjSource
17671                    + " target=" + app.adjTarget);
17672        }
17673
17674        return success;
17675    }
17676
17677    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17678        if (proc.thread != null) {
17679            if (proc.baseProcessTracker != null) {
17680                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17681            }
17682            if (proc.repProcState >= 0) {
17683                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17684                        proc.repProcState);
17685            }
17686        }
17687    }
17688
17689    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17690            ProcessRecord TOP_APP, boolean doingAll, long now) {
17691        if (app.thread == null) {
17692            return false;
17693        }
17694
17695        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17696
17697        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17698    }
17699
17700    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17701            boolean oomAdj) {
17702        if (isForeground != proc.foregroundServices) {
17703            proc.foregroundServices = isForeground;
17704            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17705                    proc.info.uid);
17706            if (isForeground) {
17707                if (curProcs == null) {
17708                    curProcs = new ArrayList<ProcessRecord>();
17709                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17710                }
17711                if (!curProcs.contains(proc)) {
17712                    curProcs.add(proc);
17713                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17714                            proc.info.packageName, proc.info.uid);
17715                }
17716            } else {
17717                if (curProcs != null) {
17718                    if (curProcs.remove(proc)) {
17719                        mBatteryStatsService.noteEvent(
17720                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17721                                proc.info.packageName, proc.info.uid);
17722                        if (curProcs.size() <= 0) {
17723                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17724                        }
17725                    }
17726                }
17727            }
17728            if (oomAdj) {
17729                updateOomAdjLocked();
17730            }
17731        }
17732    }
17733
17734    private final ActivityRecord resumedAppLocked() {
17735        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17736        String pkg;
17737        int uid;
17738        if (act != null) {
17739            pkg = act.packageName;
17740            uid = act.info.applicationInfo.uid;
17741        } else {
17742            pkg = null;
17743            uid = -1;
17744        }
17745        // Has the UID or resumed package name changed?
17746        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17747                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17748            if (mCurResumedPackage != null) {
17749                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17750                        mCurResumedPackage, mCurResumedUid);
17751            }
17752            mCurResumedPackage = pkg;
17753            mCurResumedUid = uid;
17754            if (mCurResumedPackage != null) {
17755                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17756                        mCurResumedPackage, mCurResumedUid);
17757            }
17758        }
17759        return act;
17760    }
17761
17762    final boolean updateOomAdjLocked(ProcessRecord app) {
17763        final ActivityRecord TOP_ACT = resumedAppLocked();
17764        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17765        final boolean wasCached = app.cached;
17766
17767        mAdjSeq++;
17768
17769        // This is the desired cached adjusment we want to tell it to use.
17770        // If our app is currently cached, we know it, and that is it.  Otherwise,
17771        // we don't know it yet, and it needs to now be cached we will then
17772        // need to do a complete oom adj.
17773        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17774                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17775        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17776                SystemClock.uptimeMillis());
17777        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17778            // Changed to/from cached state, so apps after it in the LRU
17779            // list may also be changed.
17780            updateOomAdjLocked();
17781        }
17782        return success;
17783    }
17784
17785    final void updateOomAdjLocked() {
17786        final ActivityRecord TOP_ACT = resumedAppLocked();
17787        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17788        final long now = SystemClock.uptimeMillis();
17789        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17790        final int N = mLruProcesses.size();
17791
17792        if (false) {
17793            RuntimeException e = new RuntimeException();
17794            e.fillInStackTrace();
17795            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17796        }
17797
17798        mAdjSeq++;
17799        mNewNumServiceProcs = 0;
17800        mNewNumAServiceProcs = 0;
17801
17802        final int emptyProcessLimit;
17803        final int cachedProcessLimit;
17804        if (mProcessLimit <= 0) {
17805            emptyProcessLimit = cachedProcessLimit = 0;
17806        } else if (mProcessLimit == 1) {
17807            emptyProcessLimit = 1;
17808            cachedProcessLimit = 0;
17809        } else {
17810            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17811            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17812        }
17813
17814        // Let's determine how many processes we have running vs.
17815        // how many slots we have for background processes; we may want
17816        // to put multiple processes in a slot of there are enough of
17817        // them.
17818        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17819                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17820        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17821        if (numEmptyProcs > cachedProcessLimit) {
17822            // If there are more empty processes than our limit on cached
17823            // processes, then use the cached process limit for the factor.
17824            // This ensures that the really old empty processes get pushed
17825            // down to the bottom, so if we are running low on memory we will
17826            // have a better chance at keeping around more cached processes
17827            // instead of a gazillion empty processes.
17828            numEmptyProcs = cachedProcessLimit;
17829        }
17830        int emptyFactor = numEmptyProcs/numSlots;
17831        if (emptyFactor < 1) emptyFactor = 1;
17832        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17833        if (cachedFactor < 1) cachedFactor = 1;
17834        int stepCached = 0;
17835        int stepEmpty = 0;
17836        int numCached = 0;
17837        int numEmpty = 0;
17838        int numTrimming = 0;
17839
17840        mNumNonCachedProcs = 0;
17841        mNumCachedHiddenProcs = 0;
17842
17843        // First update the OOM adjustment for each of the
17844        // application processes based on their current state.
17845        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17846        int nextCachedAdj = curCachedAdj+1;
17847        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17848        int nextEmptyAdj = curEmptyAdj+2;
17849        for (int i=N-1; i>=0; i--) {
17850            ProcessRecord app = mLruProcesses.get(i);
17851            if (!app.killedByAm && app.thread != null) {
17852                app.procStateChanged = false;
17853                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17854
17855                // If we haven't yet assigned the final cached adj
17856                // to the process, do that now.
17857                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17858                    switch (app.curProcState) {
17859                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17860                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17861                            // This process is a cached process holding activities...
17862                            // assign it the next cached value for that type, and then
17863                            // step that cached level.
17864                            app.curRawAdj = curCachedAdj;
17865                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17866                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17867                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17868                                    + ")");
17869                            if (curCachedAdj != nextCachedAdj) {
17870                                stepCached++;
17871                                if (stepCached >= cachedFactor) {
17872                                    stepCached = 0;
17873                                    curCachedAdj = nextCachedAdj;
17874                                    nextCachedAdj += 2;
17875                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17876                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17877                                    }
17878                                }
17879                            }
17880                            break;
17881                        default:
17882                            // For everything else, assign next empty cached process
17883                            // level and bump that up.  Note that this means that
17884                            // long-running services that have dropped down to the
17885                            // cached level will be treated as empty (since their process
17886                            // state is still as a service), which is what we want.
17887                            app.curRawAdj = curEmptyAdj;
17888                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17889                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17890                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17891                                    + ")");
17892                            if (curEmptyAdj != nextEmptyAdj) {
17893                                stepEmpty++;
17894                                if (stepEmpty >= emptyFactor) {
17895                                    stepEmpty = 0;
17896                                    curEmptyAdj = nextEmptyAdj;
17897                                    nextEmptyAdj += 2;
17898                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17899                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17900                                    }
17901                                }
17902                            }
17903                            break;
17904                    }
17905                }
17906
17907                applyOomAdjLocked(app, TOP_APP, true, now);
17908
17909                // Count the number of process types.
17910                switch (app.curProcState) {
17911                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17912                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17913                        mNumCachedHiddenProcs++;
17914                        numCached++;
17915                        if (numCached > cachedProcessLimit) {
17916                            app.kill("cached #" + numCached, true);
17917                        }
17918                        break;
17919                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17920                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17921                                && app.lastActivityTime < oldTime) {
17922                            app.kill("empty for "
17923                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17924                                    / 1000) + "s", true);
17925                        } else {
17926                            numEmpty++;
17927                            if (numEmpty > emptyProcessLimit) {
17928                                app.kill("empty #" + numEmpty, true);
17929                            }
17930                        }
17931                        break;
17932                    default:
17933                        mNumNonCachedProcs++;
17934                        break;
17935                }
17936
17937                if (app.isolated && app.services.size() <= 0) {
17938                    // If this is an isolated process, and there are no
17939                    // services running in it, then the process is no longer
17940                    // needed.  We agressively kill these because we can by
17941                    // definition not re-use the same process again, and it is
17942                    // good to avoid having whatever code was running in them
17943                    // left sitting around after no longer needed.
17944                    app.kill("isolated not needed", true);
17945                }
17946
17947                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17948                        && !app.killedByAm) {
17949                    numTrimming++;
17950                }
17951            }
17952        }
17953
17954        mNumServiceProcs = mNewNumServiceProcs;
17955
17956        // Now determine the memory trimming level of background processes.
17957        // Unfortunately we need to start at the back of the list to do this
17958        // properly.  We only do this if the number of background apps we
17959        // are managing to keep around is less than half the maximum we desire;
17960        // if we are keeping a good number around, we'll let them use whatever
17961        // memory they want.
17962        final int numCachedAndEmpty = numCached + numEmpty;
17963        int memFactor;
17964        if (numCached <= ProcessList.TRIM_CACHED_APPS
17965                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17966            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17967                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17968            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17969                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17970            } else {
17971                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17972            }
17973        } else {
17974            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17975        }
17976        // We always allow the memory level to go up (better).  We only allow it to go
17977        // down if we are in a state where that is allowed, *and* the total number of processes
17978        // has gone down since last time.
17979        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17980                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17981                + " last=" + mLastNumProcesses);
17982        if (memFactor > mLastMemoryLevel) {
17983            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17984                memFactor = mLastMemoryLevel;
17985                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17986            }
17987        }
17988        mLastMemoryLevel = memFactor;
17989        mLastNumProcesses = mLruProcesses.size();
17990        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17991        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17992        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17993            if (mLowRamStartTime == 0) {
17994                mLowRamStartTime = now;
17995            }
17996            int step = 0;
17997            int fgTrimLevel;
17998            switch (memFactor) {
17999                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18000                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18001                    break;
18002                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18003                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18004                    break;
18005                default:
18006                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18007                    break;
18008            }
18009            int factor = numTrimming/3;
18010            int minFactor = 2;
18011            if (mHomeProcess != null) minFactor++;
18012            if (mPreviousProcess != null) minFactor++;
18013            if (factor < minFactor) factor = minFactor;
18014            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18015            for (int i=N-1; i>=0; i--) {
18016                ProcessRecord app = mLruProcesses.get(i);
18017                if (allChanged || app.procStateChanged) {
18018                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18019                    app.procStateChanged = false;
18020                }
18021                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18022                        && !app.killedByAm) {
18023                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18024                        try {
18025                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18026                                    "Trimming memory of " + app.processName
18027                                    + " to " + curLevel);
18028                            app.thread.scheduleTrimMemory(curLevel);
18029                        } catch (RemoteException e) {
18030                        }
18031                        if (false) {
18032                            // For now we won't do this; our memory trimming seems
18033                            // to be good enough at this point that destroying
18034                            // activities causes more harm than good.
18035                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18036                                    && app != mHomeProcess && app != mPreviousProcess) {
18037                                // Need to do this on its own message because the stack may not
18038                                // be in a consistent state at this point.
18039                                // For these apps we will also finish their activities
18040                                // to help them free memory.
18041                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18042                            }
18043                        }
18044                    }
18045                    app.trimMemoryLevel = curLevel;
18046                    step++;
18047                    if (step >= factor) {
18048                        step = 0;
18049                        switch (curLevel) {
18050                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18051                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18052                                break;
18053                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18054                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18055                                break;
18056                        }
18057                    }
18058                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18059                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18060                            && app.thread != null) {
18061                        try {
18062                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18063                                    "Trimming memory of heavy-weight " + app.processName
18064                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18065                            app.thread.scheduleTrimMemory(
18066                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18067                        } catch (RemoteException e) {
18068                        }
18069                    }
18070                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18071                } else {
18072                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18073                            || app.systemNoUi) && app.pendingUiClean) {
18074                        // If this application is now in the background and it
18075                        // had done UI, then give it the special trim level to
18076                        // have it free UI resources.
18077                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18078                        if (app.trimMemoryLevel < level && app.thread != null) {
18079                            try {
18080                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18081                                        "Trimming memory of bg-ui " + app.processName
18082                                        + " to " + level);
18083                                app.thread.scheduleTrimMemory(level);
18084                            } catch (RemoteException e) {
18085                            }
18086                        }
18087                        app.pendingUiClean = false;
18088                    }
18089                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18090                        try {
18091                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18092                                    "Trimming memory of fg " + app.processName
18093                                    + " to " + fgTrimLevel);
18094                            app.thread.scheduleTrimMemory(fgTrimLevel);
18095                        } catch (RemoteException e) {
18096                        }
18097                    }
18098                    app.trimMemoryLevel = fgTrimLevel;
18099                }
18100            }
18101        } else {
18102            if (mLowRamStartTime != 0) {
18103                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18104                mLowRamStartTime = 0;
18105            }
18106            for (int i=N-1; i>=0; i--) {
18107                ProcessRecord app = mLruProcesses.get(i);
18108                if (allChanged || app.procStateChanged) {
18109                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18110                    app.procStateChanged = false;
18111                }
18112                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18113                        || app.systemNoUi) && app.pendingUiClean) {
18114                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18115                            && app.thread != null) {
18116                        try {
18117                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18118                                    "Trimming memory of ui hidden " + app.processName
18119                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18120                            app.thread.scheduleTrimMemory(
18121                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18122                        } catch (RemoteException e) {
18123                        }
18124                    }
18125                    app.pendingUiClean = false;
18126                }
18127                app.trimMemoryLevel = 0;
18128            }
18129        }
18130
18131        if (mAlwaysFinishActivities) {
18132            // Need to do this on its own message because the stack may not
18133            // be in a consistent state at this point.
18134            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18135        }
18136
18137        if (allChanged) {
18138            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18139        }
18140
18141        if (mProcessStats.shouldWriteNowLocked(now)) {
18142            mHandler.post(new Runnable() {
18143                @Override public void run() {
18144                    synchronized (ActivityManagerService.this) {
18145                        mProcessStats.writeStateAsyncLocked();
18146                    }
18147                }
18148            });
18149        }
18150
18151        if (DEBUG_OOM_ADJ) {
18152            if (false) {
18153                RuntimeException here = new RuntimeException("here");
18154                here.fillInStackTrace();
18155                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18156            } else {
18157                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18158            }
18159        }
18160    }
18161
18162    final void trimApplications() {
18163        synchronized (this) {
18164            int i;
18165
18166            // First remove any unused application processes whose package
18167            // has been removed.
18168            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18169                final ProcessRecord app = mRemovedProcesses.get(i);
18170                if (app.activities.size() == 0
18171                        && app.curReceiver == null && app.services.size() == 0) {
18172                    Slog.i(
18173                        TAG, "Exiting empty application process "
18174                        + app.processName + " ("
18175                        + (app.thread != null ? app.thread.asBinder() : null)
18176                        + ")\n");
18177                    if (app.pid > 0 && app.pid != MY_PID) {
18178                        app.kill("empty", false);
18179                    } else {
18180                        try {
18181                            app.thread.scheduleExit();
18182                        } catch (Exception e) {
18183                            // Ignore exceptions.
18184                        }
18185                    }
18186                    cleanUpApplicationRecordLocked(app, false, true, -1);
18187                    mRemovedProcesses.remove(i);
18188
18189                    if (app.persistent) {
18190                        addAppLocked(app.info, false, null /* ABI override */);
18191                    }
18192                }
18193            }
18194
18195            // Now update the oom adj for all processes.
18196            updateOomAdjLocked();
18197        }
18198    }
18199
18200    /** This method sends the specified signal to each of the persistent apps */
18201    public void signalPersistentProcesses(int sig) throws RemoteException {
18202        if (sig != Process.SIGNAL_USR1) {
18203            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18204        }
18205
18206        synchronized (this) {
18207            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18208                    != PackageManager.PERMISSION_GRANTED) {
18209                throw new SecurityException("Requires permission "
18210                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18211            }
18212
18213            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18214                ProcessRecord r = mLruProcesses.get(i);
18215                if (r.thread != null && r.persistent) {
18216                    Process.sendSignal(r.pid, sig);
18217                }
18218            }
18219        }
18220    }
18221
18222    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18223        if (proc == null || proc == mProfileProc) {
18224            proc = mProfileProc;
18225            profileType = mProfileType;
18226            clearProfilerLocked();
18227        }
18228        if (proc == null) {
18229            return;
18230        }
18231        try {
18232            proc.thread.profilerControl(false, null, profileType);
18233        } catch (RemoteException e) {
18234            throw new IllegalStateException("Process disappeared");
18235        }
18236    }
18237
18238    private void clearProfilerLocked() {
18239        if (mProfileFd != null) {
18240            try {
18241                mProfileFd.close();
18242            } catch (IOException e) {
18243            }
18244        }
18245        mProfileApp = null;
18246        mProfileProc = null;
18247        mProfileFile = null;
18248        mProfileType = 0;
18249        mAutoStopProfiler = false;
18250        mSamplingInterval = 0;
18251    }
18252
18253    public boolean profileControl(String process, int userId, boolean start,
18254            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18255
18256        try {
18257            synchronized (this) {
18258                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18259                // its own permission.
18260                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18261                        != PackageManager.PERMISSION_GRANTED) {
18262                    throw new SecurityException("Requires permission "
18263                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18264                }
18265
18266                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18267                    throw new IllegalArgumentException("null profile info or fd");
18268                }
18269
18270                ProcessRecord proc = null;
18271                if (process != null) {
18272                    proc = findProcessLocked(process, userId, "profileControl");
18273                }
18274
18275                if (start && (proc == null || proc.thread == null)) {
18276                    throw new IllegalArgumentException("Unknown process: " + process);
18277                }
18278
18279                if (start) {
18280                    stopProfilerLocked(null, 0);
18281                    setProfileApp(proc.info, proc.processName, profilerInfo);
18282                    mProfileProc = proc;
18283                    mProfileType = profileType;
18284                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18285                    try {
18286                        fd = fd.dup();
18287                    } catch (IOException e) {
18288                        fd = null;
18289                    }
18290                    profilerInfo.profileFd = fd;
18291                    proc.thread.profilerControl(start, profilerInfo, profileType);
18292                    fd = null;
18293                    mProfileFd = null;
18294                } else {
18295                    stopProfilerLocked(proc, profileType);
18296                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18297                        try {
18298                            profilerInfo.profileFd.close();
18299                        } catch (IOException e) {
18300                        }
18301                    }
18302                }
18303
18304                return true;
18305            }
18306        } catch (RemoteException e) {
18307            throw new IllegalStateException("Process disappeared");
18308        } finally {
18309            if (profilerInfo != null && profilerInfo.profileFd != null) {
18310                try {
18311                    profilerInfo.profileFd.close();
18312                } catch (IOException e) {
18313                }
18314            }
18315        }
18316    }
18317
18318    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18319        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18320                userId, true, ALLOW_FULL_ONLY, callName, null);
18321        ProcessRecord proc = null;
18322        try {
18323            int pid = Integer.parseInt(process);
18324            synchronized (mPidsSelfLocked) {
18325                proc = mPidsSelfLocked.get(pid);
18326            }
18327        } catch (NumberFormatException e) {
18328        }
18329
18330        if (proc == null) {
18331            ArrayMap<String, SparseArray<ProcessRecord>> all
18332                    = mProcessNames.getMap();
18333            SparseArray<ProcessRecord> procs = all.get(process);
18334            if (procs != null && procs.size() > 0) {
18335                proc = procs.valueAt(0);
18336                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18337                    for (int i=1; i<procs.size(); i++) {
18338                        ProcessRecord thisProc = procs.valueAt(i);
18339                        if (thisProc.userId == userId) {
18340                            proc = thisProc;
18341                            break;
18342                        }
18343                    }
18344                }
18345            }
18346        }
18347
18348        return proc;
18349    }
18350
18351    public boolean dumpHeap(String process, int userId, boolean managed,
18352            String path, ParcelFileDescriptor fd) throws RemoteException {
18353
18354        try {
18355            synchronized (this) {
18356                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18357                // its own permission (same as profileControl).
18358                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18359                        != PackageManager.PERMISSION_GRANTED) {
18360                    throw new SecurityException("Requires permission "
18361                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18362                }
18363
18364                if (fd == null) {
18365                    throw new IllegalArgumentException("null fd");
18366                }
18367
18368                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18369                if (proc == null || proc.thread == null) {
18370                    throw new IllegalArgumentException("Unknown process: " + process);
18371                }
18372
18373                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18374                if (!isDebuggable) {
18375                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18376                        throw new SecurityException("Process not debuggable: " + proc);
18377                    }
18378                }
18379
18380                proc.thread.dumpHeap(managed, path, fd);
18381                fd = null;
18382                return true;
18383            }
18384        } catch (RemoteException e) {
18385            throw new IllegalStateException("Process disappeared");
18386        } finally {
18387            if (fd != null) {
18388                try {
18389                    fd.close();
18390                } catch (IOException e) {
18391                }
18392            }
18393        }
18394    }
18395
18396    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18397    public void monitor() {
18398        synchronized (this) { }
18399    }
18400
18401    void onCoreSettingsChange(Bundle settings) {
18402        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18403            ProcessRecord processRecord = mLruProcesses.get(i);
18404            try {
18405                if (processRecord.thread != null) {
18406                    processRecord.thread.setCoreSettings(settings);
18407                }
18408            } catch (RemoteException re) {
18409                /* ignore */
18410            }
18411        }
18412    }
18413
18414    // Multi-user methods
18415
18416    /**
18417     * Start user, if its not already running, but don't bring it to foreground.
18418     */
18419    @Override
18420    public boolean startUserInBackground(final int userId) {
18421        return startUser(userId, /* foreground */ false);
18422    }
18423
18424    /**
18425     * Start user, if its not already running, and bring it to foreground.
18426     */
18427    boolean startUserInForeground(final int userId, Dialog dlg) {
18428        boolean result = startUser(userId, /* foreground */ true);
18429        dlg.dismiss();
18430        return result;
18431    }
18432
18433    /**
18434     * Refreshes the list of users related to the current user when either a
18435     * user switch happens or when a new related user is started in the
18436     * background.
18437     */
18438    private void updateCurrentProfileIdsLocked() {
18439        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18440                mCurrentUserId, false /* enabledOnly */);
18441        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18442        for (int i = 0; i < currentProfileIds.length; i++) {
18443            currentProfileIds[i] = profiles.get(i).id;
18444        }
18445        mCurrentProfileIds = currentProfileIds;
18446
18447        synchronized (mUserProfileGroupIdsSelfLocked) {
18448            mUserProfileGroupIdsSelfLocked.clear();
18449            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18450            for (int i = 0; i < users.size(); i++) {
18451                UserInfo user = users.get(i);
18452                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18453                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18454                }
18455            }
18456        }
18457    }
18458
18459    private Set getProfileIdsLocked(int userId) {
18460        Set userIds = new HashSet<Integer>();
18461        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18462                userId, false /* enabledOnly */);
18463        for (UserInfo user : profiles) {
18464            userIds.add(Integer.valueOf(user.id));
18465        }
18466        return userIds;
18467    }
18468
18469    @Override
18470    public boolean switchUser(final int userId) {
18471        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18472        String userName;
18473        synchronized (this) {
18474            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18475            if (userInfo == null) {
18476                Slog.w(TAG, "No user info for user #" + userId);
18477                return false;
18478            }
18479            if (userInfo.isManagedProfile()) {
18480                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18481                return false;
18482            }
18483            userName = userInfo.name;
18484            mTargetUserId = userId;
18485        }
18486        mHandler.removeMessages(START_USER_SWITCH_MSG);
18487        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18488        return true;
18489    }
18490
18491    private void showUserSwitchDialog(int userId, String userName) {
18492        // The dialog will show and then initiate the user switch by calling startUserInForeground
18493        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18494                true /* above system */);
18495        d.show();
18496    }
18497
18498    private boolean startUser(final int userId, final boolean foreground) {
18499        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18500                != PackageManager.PERMISSION_GRANTED) {
18501            String msg = "Permission Denial: switchUser() from pid="
18502                    + Binder.getCallingPid()
18503                    + ", uid=" + Binder.getCallingUid()
18504                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18505            Slog.w(TAG, msg);
18506            throw new SecurityException(msg);
18507        }
18508
18509        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18510
18511        final long ident = Binder.clearCallingIdentity();
18512        try {
18513            synchronized (this) {
18514                final int oldUserId = mCurrentUserId;
18515                if (oldUserId == userId) {
18516                    return true;
18517                }
18518
18519                mStackSupervisor.setLockTaskModeLocked(null, false);
18520
18521                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18522                if (userInfo == null) {
18523                    Slog.w(TAG, "No user info for user #" + userId);
18524                    return false;
18525                }
18526                if (foreground && userInfo.isManagedProfile()) {
18527                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18528                    return false;
18529                }
18530
18531                if (foreground) {
18532                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18533                            R.anim.screen_user_enter);
18534                }
18535
18536                boolean needStart = false;
18537
18538                // If the user we are switching to is not currently started, then
18539                // we need to start it now.
18540                if (mStartedUsers.get(userId) == null) {
18541                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18542                    updateStartedUserArrayLocked();
18543                    needStart = true;
18544                }
18545
18546                final Integer userIdInt = Integer.valueOf(userId);
18547                mUserLru.remove(userIdInt);
18548                mUserLru.add(userIdInt);
18549
18550                if (foreground) {
18551                    mCurrentUserId = userId;
18552                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18553                    updateCurrentProfileIdsLocked();
18554                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18555                    // Once the internal notion of the active user has switched, we lock the device
18556                    // with the option to show the user switcher on the keyguard.
18557                    mWindowManager.lockNow(null);
18558                } else {
18559                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18560                    updateCurrentProfileIdsLocked();
18561                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18562                    mUserLru.remove(currentUserIdInt);
18563                    mUserLru.add(currentUserIdInt);
18564                }
18565
18566                final UserStartedState uss = mStartedUsers.get(userId);
18567
18568                // Make sure user is in the started state.  If it is currently
18569                // stopping, we need to knock that off.
18570                if (uss.mState == UserStartedState.STATE_STOPPING) {
18571                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18572                    // so we can just fairly silently bring the user back from
18573                    // the almost-dead.
18574                    uss.mState = UserStartedState.STATE_RUNNING;
18575                    updateStartedUserArrayLocked();
18576                    needStart = true;
18577                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18578                    // This means ACTION_SHUTDOWN has been sent, so we will
18579                    // need to treat this as a new boot of the user.
18580                    uss.mState = UserStartedState.STATE_BOOTING;
18581                    updateStartedUserArrayLocked();
18582                    needStart = true;
18583                }
18584
18585                if (uss.mState == UserStartedState.STATE_BOOTING) {
18586                    // Booting up a new user, need to tell system services about it.
18587                    // Note that this is on the same handler as scheduling of broadcasts,
18588                    // which is important because it needs to go first.
18589                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18590                }
18591
18592                if (foreground) {
18593                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18594                            oldUserId));
18595                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18596                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18597                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18598                            oldUserId, userId, uss));
18599                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18600                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18601                }
18602
18603                if (needStart) {
18604                    // Send USER_STARTED broadcast
18605                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18606                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18607                            | Intent.FLAG_RECEIVER_FOREGROUND);
18608                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18609                    broadcastIntentLocked(null, null, intent,
18610                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18611                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18612                }
18613
18614                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18615                    if (userId != UserHandle.USER_OWNER) {
18616                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18617                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18618                        broadcastIntentLocked(null, null, intent, null,
18619                                new IIntentReceiver.Stub() {
18620                                    public void performReceive(Intent intent, int resultCode,
18621                                            String data, Bundle extras, boolean ordered,
18622                                            boolean sticky, int sendingUser) {
18623                                        onUserInitialized(uss, foreground, oldUserId, userId);
18624                                    }
18625                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18626                                true, false, MY_PID, Process.SYSTEM_UID,
18627                                userId);
18628                        uss.initializing = true;
18629                    } else {
18630                        getUserManagerLocked().makeInitialized(userInfo.id);
18631                    }
18632                }
18633
18634                if (foreground) {
18635                    if (!uss.initializing) {
18636                        moveUserToForeground(uss, oldUserId, userId);
18637                    }
18638                } else {
18639                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18640                }
18641
18642                if (needStart) {
18643                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18644                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18645                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18646                    broadcastIntentLocked(null, null, intent,
18647                            null, new IIntentReceiver.Stub() {
18648                                @Override
18649                                public void performReceive(Intent intent, int resultCode, String data,
18650                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18651                                        throws RemoteException {
18652                                }
18653                            }, 0, null, null,
18654                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18655                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18656                }
18657            }
18658        } finally {
18659            Binder.restoreCallingIdentity(ident);
18660        }
18661
18662        return true;
18663    }
18664
18665    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18666        long ident = Binder.clearCallingIdentity();
18667        try {
18668            Intent intent;
18669            if (oldUserId >= 0) {
18670                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18671                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18672                int count = profiles.size();
18673                for (int i = 0; i < count; i++) {
18674                    int profileUserId = profiles.get(i).id;
18675                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18676                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18677                            | Intent.FLAG_RECEIVER_FOREGROUND);
18678                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18679                    broadcastIntentLocked(null, null, intent,
18680                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18681                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18682                }
18683            }
18684            if (newUserId >= 0) {
18685                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18686                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18687                int count = profiles.size();
18688                for (int i = 0; i < count; i++) {
18689                    int profileUserId = profiles.get(i).id;
18690                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18691                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18692                            | Intent.FLAG_RECEIVER_FOREGROUND);
18693                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18694                    broadcastIntentLocked(null, null, intent,
18695                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18696                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18697                }
18698                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18699                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18700                        | Intent.FLAG_RECEIVER_FOREGROUND);
18701                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18702                broadcastIntentLocked(null, null, intent,
18703                        null, null, 0, null, null,
18704                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18705                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18706            }
18707        } finally {
18708            Binder.restoreCallingIdentity(ident);
18709        }
18710    }
18711
18712    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18713            final int newUserId) {
18714        final int N = mUserSwitchObservers.beginBroadcast();
18715        if (N > 0) {
18716            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18717                int mCount = 0;
18718                @Override
18719                public void sendResult(Bundle data) throws RemoteException {
18720                    synchronized (ActivityManagerService.this) {
18721                        if (mCurUserSwitchCallback == this) {
18722                            mCount++;
18723                            if (mCount == N) {
18724                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18725                            }
18726                        }
18727                    }
18728                }
18729            };
18730            synchronized (this) {
18731                uss.switching = true;
18732                mCurUserSwitchCallback = callback;
18733            }
18734            for (int i=0; i<N; i++) {
18735                try {
18736                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18737                            newUserId, callback);
18738                } catch (RemoteException e) {
18739                }
18740            }
18741        } else {
18742            synchronized (this) {
18743                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18744            }
18745        }
18746        mUserSwitchObservers.finishBroadcast();
18747    }
18748
18749    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18750        synchronized (this) {
18751            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18752            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18753        }
18754    }
18755
18756    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18757        mCurUserSwitchCallback = null;
18758        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18759        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18760                oldUserId, newUserId, uss));
18761    }
18762
18763    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18764        synchronized (this) {
18765            if (foreground) {
18766                moveUserToForeground(uss, oldUserId, newUserId);
18767            }
18768        }
18769
18770        completeSwitchAndInitalize(uss, newUserId, true, false);
18771    }
18772
18773    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18774        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18775        if (homeInFront) {
18776            startHomeActivityLocked(newUserId);
18777        } else {
18778            mStackSupervisor.resumeTopActivitiesLocked();
18779        }
18780        EventLogTags.writeAmSwitchUser(newUserId);
18781        getUserManagerLocked().userForeground(newUserId);
18782        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18783    }
18784
18785    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18786        completeSwitchAndInitalize(uss, newUserId, false, true);
18787    }
18788
18789    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18790            boolean clearInitializing, boolean clearSwitching) {
18791        boolean unfrozen = false;
18792        synchronized (this) {
18793            if (clearInitializing) {
18794                uss.initializing = false;
18795                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18796            }
18797            if (clearSwitching) {
18798                uss.switching = false;
18799            }
18800            if (!uss.switching && !uss.initializing) {
18801                mWindowManager.stopFreezingScreen();
18802                unfrozen = true;
18803            }
18804        }
18805        if (unfrozen) {
18806            final int N = mUserSwitchObservers.beginBroadcast();
18807            for (int i=0; i<N; i++) {
18808                try {
18809                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18810                } catch (RemoteException e) {
18811                }
18812            }
18813            mUserSwitchObservers.finishBroadcast();
18814        }
18815    }
18816
18817    void scheduleStartProfilesLocked() {
18818        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18819            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18820                    DateUtils.SECOND_IN_MILLIS);
18821        }
18822    }
18823
18824    void startProfilesLocked() {
18825        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18826        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18827                mCurrentUserId, false /* enabledOnly */);
18828        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18829        for (UserInfo user : profiles) {
18830            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18831                    && user.id != mCurrentUserId) {
18832                toStart.add(user);
18833            }
18834        }
18835        final int n = toStart.size();
18836        int i = 0;
18837        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18838            startUserInBackground(toStart.get(i).id);
18839        }
18840        if (i < n) {
18841            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18842        }
18843    }
18844
18845    void finishUserBoot(UserStartedState uss) {
18846        synchronized (this) {
18847            if (uss.mState == UserStartedState.STATE_BOOTING
18848                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18849                uss.mState = UserStartedState.STATE_RUNNING;
18850                final int userId = uss.mHandle.getIdentifier();
18851                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18852                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18853                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18854                broadcastIntentLocked(null, null, intent,
18855                        null, null, 0, null, null,
18856                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18857                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18858            }
18859        }
18860    }
18861
18862    void finishUserSwitch(UserStartedState uss) {
18863        synchronized (this) {
18864            finishUserBoot(uss);
18865
18866            startProfilesLocked();
18867
18868            int num = mUserLru.size();
18869            int i = 0;
18870            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18871                Integer oldUserId = mUserLru.get(i);
18872                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18873                if (oldUss == null) {
18874                    // Shouldn't happen, but be sane if it does.
18875                    mUserLru.remove(i);
18876                    num--;
18877                    continue;
18878                }
18879                if (oldUss.mState == UserStartedState.STATE_STOPPING
18880                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18881                    // This user is already stopping, doesn't count.
18882                    num--;
18883                    i++;
18884                    continue;
18885                }
18886                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18887                    // Owner and current can't be stopped, but count as running.
18888                    i++;
18889                    continue;
18890                }
18891                // This is a user to be stopped.
18892                stopUserLocked(oldUserId, null);
18893                num--;
18894                i++;
18895            }
18896        }
18897    }
18898
18899    @Override
18900    public int stopUser(final int userId, final IStopUserCallback callback) {
18901        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18902                != PackageManager.PERMISSION_GRANTED) {
18903            String msg = "Permission Denial: switchUser() from pid="
18904                    + Binder.getCallingPid()
18905                    + ", uid=" + Binder.getCallingUid()
18906                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18907            Slog.w(TAG, msg);
18908            throw new SecurityException(msg);
18909        }
18910        if (userId <= 0) {
18911            throw new IllegalArgumentException("Can't stop primary user " + userId);
18912        }
18913        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18914        synchronized (this) {
18915            return stopUserLocked(userId, callback);
18916        }
18917    }
18918
18919    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18920        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18921        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18922            return ActivityManager.USER_OP_IS_CURRENT;
18923        }
18924
18925        final UserStartedState uss = mStartedUsers.get(userId);
18926        if (uss == null) {
18927            // User is not started, nothing to do...  but we do need to
18928            // callback if requested.
18929            if (callback != null) {
18930                mHandler.post(new Runnable() {
18931                    @Override
18932                    public void run() {
18933                        try {
18934                            callback.userStopped(userId);
18935                        } catch (RemoteException e) {
18936                        }
18937                    }
18938                });
18939            }
18940            return ActivityManager.USER_OP_SUCCESS;
18941        }
18942
18943        if (callback != null) {
18944            uss.mStopCallbacks.add(callback);
18945        }
18946
18947        if (uss.mState != UserStartedState.STATE_STOPPING
18948                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18949            uss.mState = UserStartedState.STATE_STOPPING;
18950            updateStartedUserArrayLocked();
18951
18952            long ident = Binder.clearCallingIdentity();
18953            try {
18954                // We are going to broadcast ACTION_USER_STOPPING and then
18955                // once that is done send a final ACTION_SHUTDOWN and then
18956                // stop the user.
18957                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18958                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18959                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18960                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18961                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18962                // This is the result receiver for the final shutdown broadcast.
18963                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18964                    @Override
18965                    public void performReceive(Intent intent, int resultCode, String data,
18966                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18967                        finishUserStop(uss);
18968                    }
18969                };
18970                // This is the result receiver for the initial stopping broadcast.
18971                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18972                    @Override
18973                    public void performReceive(Intent intent, int resultCode, String data,
18974                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18975                        // On to the next.
18976                        synchronized (ActivityManagerService.this) {
18977                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18978                                // Whoops, we are being started back up.  Abort, abort!
18979                                return;
18980                            }
18981                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18982                        }
18983                        mBatteryStatsService.noteEvent(
18984                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18985                                Integer.toString(userId), userId);
18986                        mSystemServiceManager.stopUser(userId);
18987                        broadcastIntentLocked(null, null, shutdownIntent,
18988                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18989                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18990                    }
18991                };
18992                // Kick things off.
18993                broadcastIntentLocked(null, null, stoppingIntent,
18994                        null, stoppingReceiver, 0, null, null,
18995                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18996                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18997            } finally {
18998                Binder.restoreCallingIdentity(ident);
18999            }
19000        }
19001
19002        return ActivityManager.USER_OP_SUCCESS;
19003    }
19004
19005    void finishUserStop(UserStartedState uss) {
19006        final int userId = uss.mHandle.getIdentifier();
19007        boolean stopped;
19008        ArrayList<IStopUserCallback> callbacks;
19009        synchronized (this) {
19010            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19011            if (mStartedUsers.get(userId) != uss) {
19012                stopped = false;
19013            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19014                stopped = false;
19015            } else {
19016                stopped = true;
19017                // User can no longer run.
19018                mStartedUsers.remove(userId);
19019                mUserLru.remove(Integer.valueOf(userId));
19020                updateStartedUserArrayLocked();
19021
19022                // Clean up all state and processes associated with the user.
19023                // Kill all the processes for the user.
19024                forceStopUserLocked(userId, "finish user");
19025            }
19026
19027            // Explicitly remove the old information in mRecentTasks.
19028            removeRecentTasksForUserLocked(userId);
19029        }
19030
19031        for (int i=0; i<callbacks.size(); i++) {
19032            try {
19033                if (stopped) callbacks.get(i).userStopped(userId);
19034                else callbacks.get(i).userStopAborted(userId);
19035            } catch (RemoteException e) {
19036            }
19037        }
19038
19039        if (stopped) {
19040            mSystemServiceManager.cleanupUser(userId);
19041            synchronized (this) {
19042                mStackSupervisor.removeUserLocked(userId);
19043            }
19044        }
19045    }
19046
19047    @Override
19048    public UserInfo getCurrentUser() {
19049        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19050                != PackageManager.PERMISSION_GRANTED) && (
19051                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19052                != PackageManager.PERMISSION_GRANTED)) {
19053            String msg = "Permission Denial: getCurrentUser() from pid="
19054                    + Binder.getCallingPid()
19055                    + ", uid=" + Binder.getCallingUid()
19056                    + " requires " + INTERACT_ACROSS_USERS;
19057            Slog.w(TAG, msg);
19058            throw new SecurityException(msg);
19059        }
19060        synchronized (this) {
19061            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19062            return getUserManagerLocked().getUserInfo(userId);
19063        }
19064    }
19065
19066    int getCurrentUserIdLocked() {
19067        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19068    }
19069
19070    @Override
19071    public boolean isUserRunning(int userId, boolean orStopped) {
19072        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19073                != PackageManager.PERMISSION_GRANTED) {
19074            String msg = "Permission Denial: isUserRunning() from pid="
19075                    + Binder.getCallingPid()
19076                    + ", uid=" + Binder.getCallingUid()
19077                    + " requires " + INTERACT_ACROSS_USERS;
19078            Slog.w(TAG, msg);
19079            throw new SecurityException(msg);
19080        }
19081        synchronized (this) {
19082            return isUserRunningLocked(userId, orStopped);
19083        }
19084    }
19085
19086    boolean isUserRunningLocked(int userId, boolean orStopped) {
19087        UserStartedState state = mStartedUsers.get(userId);
19088        if (state == null) {
19089            return false;
19090        }
19091        if (orStopped) {
19092            return true;
19093        }
19094        return state.mState != UserStartedState.STATE_STOPPING
19095                && state.mState != UserStartedState.STATE_SHUTDOWN;
19096    }
19097
19098    @Override
19099    public int[] getRunningUserIds() {
19100        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19101                != PackageManager.PERMISSION_GRANTED) {
19102            String msg = "Permission Denial: isUserRunning() from pid="
19103                    + Binder.getCallingPid()
19104                    + ", uid=" + Binder.getCallingUid()
19105                    + " requires " + INTERACT_ACROSS_USERS;
19106            Slog.w(TAG, msg);
19107            throw new SecurityException(msg);
19108        }
19109        synchronized (this) {
19110            return mStartedUserArray;
19111        }
19112    }
19113
19114    private void updateStartedUserArrayLocked() {
19115        int num = 0;
19116        for (int i=0; i<mStartedUsers.size();  i++) {
19117            UserStartedState uss = mStartedUsers.valueAt(i);
19118            // This list does not include stopping users.
19119            if (uss.mState != UserStartedState.STATE_STOPPING
19120                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19121                num++;
19122            }
19123        }
19124        mStartedUserArray = new int[num];
19125        num = 0;
19126        for (int i=0; i<mStartedUsers.size();  i++) {
19127            UserStartedState uss = mStartedUsers.valueAt(i);
19128            if (uss.mState != UserStartedState.STATE_STOPPING
19129                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19130                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19131                num++;
19132            }
19133        }
19134    }
19135
19136    @Override
19137    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19138        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19139                != PackageManager.PERMISSION_GRANTED) {
19140            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19141                    + Binder.getCallingPid()
19142                    + ", uid=" + Binder.getCallingUid()
19143                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19144            Slog.w(TAG, msg);
19145            throw new SecurityException(msg);
19146        }
19147
19148        mUserSwitchObservers.register(observer);
19149    }
19150
19151    @Override
19152    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19153        mUserSwitchObservers.unregister(observer);
19154    }
19155
19156    private boolean userExists(int userId) {
19157        if (userId == 0) {
19158            return true;
19159        }
19160        UserManagerService ums = getUserManagerLocked();
19161        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19162    }
19163
19164    int[] getUsersLocked() {
19165        UserManagerService ums = getUserManagerLocked();
19166        return ums != null ? ums.getUserIds() : new int[] { 0 };
19167    }
19168
19169    UserManagerService getUserManagerLocked() {
19170        if (mUserManager == null) {
19171            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19172            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19173        }
19174        return mUserManager;
19175    }
19176
19177    private int applyUserId(int uid, int userId) {
19178        return UserHandle.getUid(userId, uid);
19179    }
19180
19181    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19182        if (info == null) return null;
19183        ApplicationInfo newInfo = new ApplicationInfo(info);
19184        newInfo.uid = applyUserId(info.uid, userId);
19185        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19186                + info.packageName;
19187        return newInfo;
19188    }
19189
19190    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19191        if (aInfo == null
19192                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19193            return aInfo;
19194        }
19195
19196        ActivityInfo info = new ActivityInfo(aInfo);
19197        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19198        return info;
19199    }
19200
19201    private final class LocalService extends ActivityManagerInternal {
19202        @Override
19203        public void goingToSleep() {
19204            ActivityManagerService.this.goingToSleep();
19205        }
19206
19207        @Override
19208        public void wakingUp() {
19209            ActivityManagerService.this.wakingUp();
19210        }
19211
19212        @Override
19213        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19214                String processName, String abiOverride, int uid, Runnable crashHandler) {
19215            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19216                    processName, abiOverride, uid, crashHandler);
19217        }
19218    }
19219
19220    /**
19221     * An implementation of IAppTask, that allows an app to manage its own tasks via
19222     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19223     * only the process that calls getAppTasks() can call the AppTask methods.
19224     */
19225    class AppTaskImpl extends IAppTask.Stub {
19226        private int mTaskId;
19227        private int mCallingUid;
19228
19229        public AppTaskImpl(int taskId, int callingUid) {
19230            mTaskId = taskId;
19231            mCallingUid = callingUid;
19232        }
19233
19234        private void checkCaller() {
19235            if (mCallingUid != Binder.getCallingUid()) {
19236                throw new SecurityException("Caller " + mCallingUid
19237                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19238            }
19239        }
19240
19241        @Override
19242        public void finishAndRemoveTask() {
19243            checkCaller();
19244
19245            synchronized (ActivityManagerService.this) {
19246                long origId = Binder.clearCallingIdentity();
19247                try {
19248                    if (!removeTaskByIdLocked(mTaskId, false)) {
19249                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19250                    }
19251                } finally {
19252                    Binder.restoreCallingIdentity(origId);
19253                }
19254            }
19255        }
19256
19257        @Override
19258        public ActivityManager.RecentTaskInfo getTaskInfo() {
19259            checkCaller();
19260
19261            synchronized (ActivityManagerService.this) {
19262                long origId = Binder.clearCallingIdentity();
19263                try {
19264                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19265                    if (tr == null) {
19266                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19267                    }
19268                    return createRecentTaskInfoFromTaskRecord(tr);
19269                } finally {
19270                    Binder.restoreCallingIdentity(origId);
19271                }
19272            }
19273        }
19274
19275        @Override
19276        public void moveToFront() {
19277            checkCaller();
19278
19279            final TaskRecord tr;
19280            synchronized (ActivityManagerService.this) {
19281                tr = recentTaskForIdLocked(mTaskId);
19282                if (tr == null) {
19283                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19284                }
19285                if (tr.getRootActivity() != null) {
19286                    moveTaskToFrontLocked(tr.taskId, 0, null);
19287                    return;
19288                }
19289            }
19290
19291            startActivityFromRecentsInner(tr.taskId, null);
19292        }
19293
19294        @Override
19295        public int startActivity(IBinder whoThread, String callingPackage,
19296                Intent intent, String resolvedType, Bundle options) {
19297            checkCaller();
19298
19299            int callingUser = UserHandle.getCallingUserId();
19300            TaskRecord tr;
19301            IApplicationThread appThread;
19302            synchronized (ActivityManagerService.this) {
19303                tr = recentTaskForIdLocked(mTaskId);
19304                if (tr == null) {
19305                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19306                }
19307                appThread = ApplicationThreadNative.asInterface(whoThread);
19308                if (appThread == null) {
19309                    throw new IllegalArgumentException("Bad app thread " + appThread);
19310                }
19311            }
19312            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19313                    resolvedType, null, null, null, null, 0, 0, null, null,
19314                    null, options, callingUser, null, tr);
19315        }
19316
19317        @Override
19318        public void setExcludeFromRecents(boolean exclude) {
19319            checkCaller();
19320
19321            synchronized (ActivityManagerService.this) {
19322                long origId = Binder.clearCallingIdentity();
19323                try {
19324                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19325                    if (tr == null) {
19326                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19327                    }
19328                    Intent intent = tr.getBaseIntent();
19329                    if (exclude) {
19330                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19331                    } else {
19332                        intent.setFlags(intent.getFlags()
19333                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19334                    }
19335                } finally {
19336                    Binder.restoreCallingIdentity(origId);
19337                }
19338            }
19339        }
19340    }
19341}
19342